Как я могу подключиться к Tcp-серверу с помощью веб-браузера? - PullRequest
0 голосов
/ 03 марта 2020

NB Те, кто комментирует этот вопрос, являются широкими (также, при голосовании и закрытии): вам не нужно фокусироваться на деталях. Единственная проблема заключается в возможности использования браузера.


Справочная информация о проблеме:

У меня есть требование, что: У меня есть клиент ( myClient.exe ) и один сервер ( myServer.exe ), который прослушивает порт № 43.

Клиент может отправить как WHOIS , так и HTTP (0.9, 1.0 и 1.1) стиль команд GET / PUT / POST для сервера, и сервер должен быть в состоянии понимать и отвечать на команды любого стиля.

Пользователи должны иметь возможность подключаться к серверу также с помощью веб-браузеров.


Что у меня в руке:

Я уже внедрил правила WHOIS и HTTP. Единственная проблема, с которой я сталкиваюсь, это то, что я не могу подключиться к серверу, используя обычный браузер inte rnet.

Сервер работает по адресу localhost:5000. Я попытался подключиться к серверу, используя Internet-Explorer, и мне это не удалось. Браузер продолжает пытаться и в конечном итоге показывает страницу сбоя.

enter image description here

Что мне нужно сейчас:

I нужно предложение, чтобы я мог изменить свой код для подключения моего браузера к myServer.exe .


Исходный код:

Исходный код для ClientClass is here .

Сервер

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();
        }
    }
}

Клиент

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
}

1 Ответ

1 голос
/ 15 марта 2020

Простой HTTP-совместимый сервер находится всего в нескольких шагах от двоичного сервера сокетов. Вы уже пишете ответ клиенту. Если первая строка ответа соответствует стандарту HTTP, браузер сможет отобразить его.

Для иллюстрации приведем несколько строк кода из одного из моих недавних проектов.

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 поддерживает подробную документацию по структуре сообщений HTTP-запросов и ответов на https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages.

...