N.B. Those who are commenting this question is broad(also, down-voting and closing): you don't need to focus on the details. The only problem is to be able to use browser.
Background of the problem:
I have a requirement that: I have a client (myClient.exe) and one server (myServer.exe) which is listening to port #43.
The client can send both WHOIS and HTTP (0.9, 1.0, and 1.1)-style GET/PUT/POST commands to the server, and the server should be able to understand and respond to any style of command.
The users should be able to be connected to the server using web browsers also.
What I have in my hand:
I already implemented WHOIS and HTTP rules. The only problem I am facing is, I can't connect to the server using a normal internet browser.
The server runs at localhost:5000
address. I tried to connect to the server using Internet-Explorer and I failed. The browser keeps trying and eventually shows a failure page.
What I need now:
I need a suggestion so that I can modify my code to connect my browser to the myServer.exe.
Source Code:
The source code for ClientClass
is here.
Server
class ServerProgram
{
static Dictionary<string, string> NameLocationDictionary;
static Dictionary<string, ClientClass> ClientDictionary;
static void Main(string[] args)
{
Console.Title = "Server";
CommandLineParser parser = new CommandLineParser();
parser.Args = new List<string>(args);
parser.FlagChar = new List<string>(new string[] {"-"});
parser.Acquire();
if (parser.Count > 0)
{
//TODO: log file save
if (parser.ContainsOption("-l"))
{
OptionArgsPosition oap = parser.GetArgument("-l");
if (oap != null)
{
LogFile.Name = oap.Argument;
parser.Remove("-l");
}
}
if (parser.ContainsOption("-f"))
{
OptionArgsPosition oap = parser.GetArgument("-f");
if (oap != null)
{
TextFile txtFile = new TextFile();
txtFile.Name = oap.Argument;
string text = txtFile.Read();
string[] lines = text.Split(new string []{ "\r\n"}, StringSplitOptions.RemoveEmptyEntries);
//load to name-location dictionary
foreach (string s in lines)
{
string [] keyValue = s.Split(',');
if (NameLocationDictionary == null)
{
NameLocationDictionary = new Dictionary<string, string>();
}
NameLocationDictionary.Add(keyValue[0], keyValue[1]);
}
parser.Remove("-f");
}
}
}
ClientDictionary = new Dictionary<string, ClientClass>();
if (NameLocationDictionary == null)
{
NameLocationDictionary = new Dictionary<string, string>();
NameLocationDictionary.Add("TONY4", "TONY4-location");
NameLocationDictionary.Add("xyzgy", "xyzgy-location");
NameLocationDictionary.Add("cssbct", "RB-336");
}
if (string.IsNullOrEmpty(LogFile.Name) || string.IsNullOrWhiteSpace(LogFile.Name))
{
LogFile.Name = "log.txt";
}
string ipAddress = Constants.LOCAL_HOST_IP;
int portNo = Constants.PORT_NO;
IPAddress ip = IPAddress.Parse(ipAddress);
TcpListener listener = new TcpListener(ip, portNo);
listener.Start();
Console.WriteLine("Server program started on address [" + Constants.LOCAL_HOST_IP + ":" + Constants.PORT_NO + "]");
//// poll for TCP clients in a 2nd thread
Thread incomingClientThread = new Thread(delegate ()
{
ServerProgram.PollIncomingClientConns(listener);
});
incomingClientThread.Start();
Console.ReadLine();
}
#region catching client connections
static void PollIncomingClientConns(TcpListener listener)
{
try
{
bool keepRunning = true;
while (keepRunning)
{
ClientClass client = new ClientClass(listener);
if (client.IsConnected)
{
Console.WriteLine("Server connected with client [{0}]", client.ID);
ClientDictionary.Add(client.ID, client);
Thread thread = new Thread(delegate ()
{
ServerProgram.ReadFromClient(client);
});
thread.Start();
}
}
throw new Exception();
}
catch (Exception ex)
{
var inner = ex.InnerException as SocketException;
if (inner != null && inner.SocketErrorCode == SocketError.ConnectionReset)
Console.WriteLine("Disconnected in [ServerProgram.Main.catch]");
else
Console.WriteLine(ex.Message);
listener.Stop();
}
}
#endregion
static void ReadFromClient(ClientClass client)
{
try
{
Console.WriteLine("New Thread of [{0}] in [ServerProgram.ReadfromClient", client.ID);
CommandLineParser parser = new CommandLineParser();
parser.FlagChar = new List<string>(new string[] {"-"});
while (client.Tcp.Connected)
{
string args = client.Read();
args = args.Replace('\r', ' ');
args = args.Replace('\n', ' ');
Regex r = new Regex("([^\" ][^ ]*)|(\"[^\"]*\")");
string [] splittedArgs = r.Matches(args).OfType<Match>().Select(m => m.Value).ToArray();
parser.Args = new List<string>(splittedArgs);
parser.Acquire();
if(args.Contains("GET") || args.Contains("PUT") || args.Contains("POST"))
{
List<string> commands = parser.Args;
commands[1] = commands[1].TrimStart(new char[] { '/', ' ', '?'});//recover [name]
if (!args.Contains("HTTP")) // HTTP 0.9
{
#region HTTP 0.9
if (commands[0] == "GET")//HTTP-0.9 request received
{
if (NameLocationDictionary.ContainsKey(commands[1]))
{
string location = NameLocationDictionary[commands[1]];
string responseText = Http09Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.OK);
}
else
{
string responseText = Http09Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.UNKNOWN);
}
}
if (commands[0] == "PUT")
{
if (NameLocationDictionary.ContainsKey(commands[1]))//update [location]
{
NameLocationDictionary[commands[1]] = commands[2];
string responseText = Http09Text.PUT_name_location_Response_Success_5(commands[2]);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "PUT " + commands[1] + " " + commands[2], ActionType.OK);
}
else
{
string responseText = Http09Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "PUT " + commands[1] + " " + commands[2], ActionType.UNKNOWN);
}
}
#endregion
}
else // HTTP 1.0, or, HTTP 1.1 ...
{
#region HTTP 1.0
if (args.Contains(Constants.HTTP10))
{
if (commands[0] == "GET")//HTTP-1.0 request received
{
if (NameLocationDictionary.ContainsKey(commands[1]))
{
string location = NameLocationDictionary[commands[1]];
string responseText = Http10Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.OK);
}
else
{
string responseText = Http10Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.UNKNOWN);
}
}
if (commands[0] == "POST")
{
List<string> comms = commands;
string key = comms[1];
string location = comms[comms.Count - 1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = location;
string responseText = Http10Text.PUT_name_location_Response_Success_5();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.OK);
}
else
{
string responseText = Http10Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.UNKNOWN);
}
}
}
#endregion
#region HTTP 1.1
if (args.Contains(Constants.HTTP11))
{
if (commands[0] == "GET")//HTTP-1.0 request received
{
string key = commands[1];
if (NameLocationDictionary.ContainsKey(key))
{
string location = NameLocationDictionary[key];
string responseText = Http11Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.OK);
}
else
{
string responseText = Http11Text.GET_POST_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.UNKNOWN);
}
}
if (commands[0] == "POST")
{
string lastLine = commands[commands.Count - 1];
string[] keyLocation = lastLine.Split('&');
string[] keyKey = keyLocation[0].Split('=');
string[] locLoc = keyLocation[1].Split('=');
string key = keyKey[1];
string location = locLoc[1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = location;
string responseText = Http11Text.POST_name_location_Response_Success_5();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.OK);
}
else
{
string responseText = Http11Text.GET_POST_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.UNKNOWN);
}
}
}
#endregion
}
}
else
{
#region WHOIS
List<string> comms = parser.Args;
int argCount = comms.Count;
if (argCount == 1)//return location
{
string key = comms[0];
if (NameLocationDictionary.ContainsKey(key))
{
string value = NameLocationDictionary[key];
string text = key + " is in " + value;
client.Write(text);
client.Disconnect();
Console.WriteLine(text);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.OK);
}
else
{
client.Write("ERROR: no entries found!");
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.UNKNOWN);
}
}
if (argCount == 2)
{
string key = comms[0];
string value = comms[1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = value;
client.Write(key + " is in " + value);
client.Disconnect();
Console.WriteLine(key + " is in " + value);
LogFile.Write(client.ClienIPAddess, "PUT " + key + " " + value, ActionType.OK);
}
else
{
client.Write("ERROR: no entries found!");
}
}
#endregion
}
}
}
catch(Exception ex)
{
client.Disconnect();
ClientDictionary.Remove(client.ID);
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
static void ListConnectedClients()
{
while (true)
{
Console.Write("Command prompt # ");
string command = Console.ReadLine();
}
}
}
Client
public class ClientProgram
{
static string clientID = string.Empty;
static string otherClientID = string.Empty;
static string host = string.Empty;
static int port = -99;
#region void Start()
public static void Start(string[] args)
{
try
{
CommandLineParser parser = new CommandLineParser();
parser.Args = new List<string>(args);
parser.FlagChar = new List<string>(new string[] { "-" });
parser.Acquire();
host = Constants.LOCAL_HOST_IP;
port = Constants.PORT_NO;
if (parser.Options != null)
{
if (parser.Options.Contains("-h"))
{
OptionArgsPosition oap = parser.GetArgument("-h");
if (oap != null)
{
if (oap.Argument != null)
{
host = oap.Argument;
parser.Remove("-h");
}
}
}
if (parser.Options.Contains("-p"))
{
OptionArgsPosition oap = parser.GetArgument("-p");
if (oap != null)
{
if (oap.Argument != null)
{
port = Convert.ToInt32(oap.Argument);
parser.Remove("-p");
}
}
}
if (parser.Options.Contains("-h0")
|| parser.Options.Contains("-h1")
|| parser.Options.Contains("-h9"))
{//HTTPClient
string name = String.Empty;
string location = String.Empty;
//Task<string> response = MyHttpClientClass.Getrequest(ip, port.ToString());
ClientClass client = new ClientClass(host, port);
try
{
Console.Title = "Client " + "[" + client.ID + "]";
bool success = client.Connect();
if (success)
{
Console.WriteLine("Client [{0}] is connected.", client.ID);
ClientProgram.WriteToHttpServer(client, parser);
}
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
}
else//TCP client
{
ClientClass client = new ClientClass(host, port);
try
{
Console.Title = "Client " + "[" + client.ID + "]";
bool success = client.Connect();
if (success)
{
Console.WriteLine("Client [{0}] is connected.", client.ID);
ClientProgram.WriteToTcpServer(client, parser);
}
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static void WriteToHttpServer(ClientClass client, CommandLineParser parser)
{
try
{
if (client.Tcp.Connected)
{
if (parser.Count < 0)
{
client.Disconnect();
Environment.Exit(0);
}
else
{
if (parser.Options.Contains("-h9"))
{
parser.Remove("-h9");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /" + oap.Option + "\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "PUT /" + oapName.Option + "\r\n\r\n" + oapLocation.Option + "\r\n";
client.Write(str);
}
}
}
if (parser.Options.Contains("-h0"))
{
parser.Remove("-h0");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /?" + oap.Option + " HTTP/1.0\r\n<optional header lines>\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "POST /" + oapName.Option + " HTTP/1.0\r\nContent-Length: 72\r\n<optional header lines>\r\n" + oapLocation.Option;
client.Write(str);
}
}
}
if (parser.Options.Contains("-h1"))
{
parser.Remove("-h1");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /?" + oap.Option + " HTTP/1.1\r\nHost: " + host + "\r\n<optional header lines>\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "POST HTTP/1.1\r\nHost: " + host + "\r\nContent-Length: 72\r\n<optional header lines>\r\nname=" + oapName.Option + "&location=" + oapLocation.Option;
client.Write(str);
}
}
}
Console.WriteLine(parser[0].Option);
Console.WriteLine("From server : " + client.Read());
}
}
Console.WriteLine("ClientProgram.WriteToTcpServer.Done");
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
#endregion
#region void WriteToServer()
private static void WriteToTcpServer(ClientClass client, CommandLineParser commands)
{
//...
}
#endregion
}
A simple HTTP-compatible server is just a few steps ahead of a binary socket server. You're already writing a response to the client. If the first line of the response follows the HTTP standard, a browser will be able to display it.
To illustrate, here are a few lines of code from one of my recent projects.
var message = new StringBuilder();
message.Append("HTTP/1.1 200 OK\n\n");
var length = message.Length;
var outgoingBuffer = new ArraySegment<byte>(Encoding.ASCII.GetBytes(message.ToString()));
_client.Close();
MDN maintains detailed documentation on the structure of HTTP request and response messages at https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages.