Метод подключения от клиента застревает при чтении ответа от сервера

#c# #server #tcp #client #streamwriter

#c# #сервер #tcp #клиент #streamwriter

Вопрос:

У меня есть клиент и серверное приложение. Сервер запускается и после запуска ожидает подключения, как обычно. Клиент отправляет свой запрос через пользовательский класс, который я назвал SocketMessage, SocketMessage просто сохраняет имя пользователя клиента и строку, содержащую метод, который клиент хочет запросить на сервере. Сервер получает SocketMessage, десериализует его и считывает строку, указывающую метод, из которой он выбирает метод для выполнения на основе инструкции switch.

Я могу отправить запрос от клиента, получить его на сервере и отправить ответ, но обратно на клиенте, при попытке прочитать ответ, метод подключения клиента блокируется в StreamReader.ReadLine

Это СЕРВЕР, связь с клиентом выполняется в рамках подпроцесса.

 private void ClientCommunication(object cliente)
        {
            TcpClient tcCliente = (TcpClient)cliente;
            StreamReader reader = new StreamReader(tcCliente.GetStream());
            StreamWriter serverStreamWriter = new StreamWriter(tcCliente.GetStream());

            while (serverOn)
            {

                try
                {
                    
                    var msj= reader.ReadLine();
                    SocketMessage<object> msjReceived= JsonConvert.DeserializeObject<SocketMessage<object>>(msj);
                    
                    
                        SelectMethod(msjReceived.Method, msj, ref serverStreamWriter);
                    
                }
                catch (Exception ex)
                {
                   
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                }
            }

            tcCliente.Close();
        }

public void SelectMethod(string pMethod, string pMsj, ref StreamWriter serverStreamWriter)
        {
            switch (pMethod)
            {
                case "CONNECT":
               
                    SocketMessage<string> connectMsj = JsonConvert.DeserializeObject<SocketMessage<string>>(pMsj);  
                        LogConnection(connectMsj.Entidad);
                        serverStreamWriter.Write("CONNECTED");
                        serverStreamWriter.Flush();
                    break;
                default:
                    break;
            }
        }
  

И это пользовательский класс для клиента, который обрабатывает отправку запросов.

 public string RequestConnection(string pUsername)
        {
            try
            {
                
                ipServer = IPAddress.Parse("127.0.0.1");
                client = new TcpClient();
                serverEndPoint = new IPEndPoint(ipServer, 16830);
               
                client.Connect(serverEndPoint);
                string serverRsp;

                SocketMessage<string> connectionRequest= new MensajeSocket<string> { Method= "CONNECT", Entity = pUsername};
                
                clientStreamReader = new StreamReader(cliente.GetStream());
                clientStreamWriter = new StreamWriter(cliente.GetStream());
                
                clientStreamWriter.WriteLine(JsonConvert.SerializeObject(connectionRequest));
                clientStreamWriter.Flush();
                Console.WriteLine("request SENT");
                //THIS is where it gets stuck
                serverRsp = clientStreamReader.ReadLine();
                Console.WriteLine("streamReader READ "   serverRsp);
                
                return serverRsp;
            }
            catch (SocketException ex)
            {
                Console.WriteLine(ex.Message);
                return ex.Message;
            }    
        }
  

Почему он застревает при нажатии serverRsp = clientStreamReader.ReadLine(); ? Я знаю, что строка чтения блокируется до тех пор, пока не будет получен ответ, но я отправляю ответ с сервера. Я подтвердил, что сервер действительно получает запрос и правильно регистрирует его, но, похоже, клиент не может прочитать соответствующее сообщение «ПОДКЛЮЧЕНО», есть идеи, что происходит?

Ответ №1:

ReadLine() ожидает завершения перевода строки в полезной нагрузке. Где, поскольку ваш клиент только отправляет Write() , WriteLine() добавит перевод строки в конец полезной нагрузки, таким образом, сервер / прослушиватель знает, когда прекратить прослушивание данных.

 serverStreamWriter.Write("CONNECTED");