-4

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.

enter image description here

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
}
user207421
  • 305,947
  • 44
  • 307
  • 483
user366312
  • 16,949
  • 65
  • 235
  • 452
  • Browsers speak HTTP. Your server doesn't. Your question doesn't make sense. You would have to enhance your server to speak HTTP, which is a vast undertaking. – user207421 Mar 09 '20 at 22:29
  • So you have to implement WHOIS as well as HTTP. Too broad, and getting broader. – user207421 Mar 09 '20 at 22:53
  • I agree it's very broad and I'm not sure if listening on a tcp port is a good idea for this or not without more context. You may wish to look into WebSockets to see if it's useful to you: https://www.html5rocks.com/en/tutorials/websockets/basics/ – Alex KeySmith Mar 09 '20 at 23:11
  • There is no evidence of your having already implemented either HTTP or WHOIS in your question, so you can't rationally be surprised that nobody knows about it. And clearly you haven't done so correctly, otherwise your browser would work. So you need to post the actual code. And an actual error message or response, rather than just repeating 'cannot connect to the server using a normal internet browser' and 'I failed'. Your question is not complete and not anwerable in its present form. – user207421 Mar 09 '20 at 23:30
  • Sigh. That's one answer to three questions. What did the browser show you, and what did you send to it? – user207421 Mar 10 '20 at 00:16
  • Double sigh. 1. You still haven't told us what the browser displayed. 2. You need to send *HTTP* to the client, with HTML *in the body.* You are still not even starting to provide enough information. I'm not asking for a description of what you send. I'm asking *what you sent*, and I am expecting you to edit the entire transmitted response into your question. 3. As to whatever you may mean by 'client ID' or 'browser ID' or 'ID mechanism', or why you think you need them, I have no idea. – user207421 Mar 10 '20 at 00:31
  • Your response HTTP is not correct. See RFC 2616 and successors. Too broad. – user207421 Mar 10 '20 at 02:26
  • Don't delete your code. Code that forms part of a question must be poseted here in the question. Not via a link. – user207421 Mar 11 '20 at 00:25
  • From Googling that looks like C# code too - want to tag question with that as well? – JGFMK Mar 16 '20 at 15:57

1 Answers1

1

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.

Pranav Negandhi
  • 1,594
  • 1
  • 8
  • 17