首页 > 解决方案 > StreamReader 似乎在 ReadLine() 之后前进,即使没有什么可读的

问题描述

我有一个客户端/服务器应用程序。在我的客户端应用程序上有一个循环来处理客户端通信。有一个带有 ReadLine 命令的 StreamReader。该命令保持锁定状态,直到它收到要读取的内容。但是,在我的情况下,在发送 1 个请求之后,在下一个周期中,即使没有发送任何消息,程序也会在达到 ReadLine 之后继续前进。这会在下一行中引发异常,我试图在上面的行中解除我收到的消息,因为它试图解除对null

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

            while (serverIsOn)
            {

                try
                {
                    //This line should be blocked until there's actually something to read.
                     
                    var message= reader.ReadLine();
                    //But after handling one request, it moves to this line on its own even if there's no message yet
                    SocketMessage<object> requestReceived= JsonConvert.DeserializeObject<SocketMessage<object>>(message);//And this is where the exception gets thrown from, because message is eventually null.
                    if (!connectedClientsDict.ContainsKey(requestReceived.Entity.ToString())){
                        connectedClientsDict.Add(requestReceived.Entity.ToString(), tcClient);
                        SelectMethod(requestReceived.Method, message, ref serverStreamWriter);
                    } else
                    {
                        SelectMethod(requestReceived.Metodo, message, ref serverStreamWriter);
                    }
                }
                catch (Exception ex)
                {
                    
                    MessageBox.Show(ex.Message, "Error in ClientCommunication", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                }
            }
tcClient.Close();
}

这是 SelectMethod 方法

public void SelectMethod(string pMethod, string pMessage, ref StreamWriter serverStreamWriter)
        {
            switch (pMethod)
            {
             case "RegisterEmployee":
                
                try {
                    semaphore = new Semaphore(1, 1);
                    semaphore.WaitOne();
                    SocketMessage<Employee> employeeToRegister = JsonConvert.DeserializeObject<SocketMessage<Employee>>(pMessage);
                    data.RegisterEmployee(employeeToRegister.Entity);
                    SocketMessage<string> serverRsp = new SocketMessage<string> { Entity= "SERVER", Method= "SUCCESS" };
                    serverStreamWriter.WriteLine(JsonConvert.SerializeObject(serverRsp));
                    serverStreamWriter.Flush();
                    semaphore.Release();
                    break;
                } catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    SocketMessage<string> serverRsp= new SocketMessage<string> { Entity = ex.Message.ToString(),
                        Method = "EMPLOYEE ALREADY EXISTS" };
                    serverStreamWriter.WriteLine(JsonConvert.SerializeObject(serverRsp));
                    serverStreamWriter.Flush();
                    semaphore.Release();
                    break;
                }

            default:
                break;
        }
    }

这是从客户端发送的方法,以防万一。

public SocketMessage<string> RequestEmployeeRegistration(Employee emp)
        {
            try
            {
                serverIp = IPAddress.Parse("127.0.0.1");
                client = new TcpClient();
                serverEndPoint = new IPEndPoint(serverIp, 16830);
                SocketMessage<string> serverRsp;
                string serializedRsp;
                client.Connect(serverEndPoint);
                SocketMessage<Emp> empToRegister = new SocketMessage<Employee> { Method = "RegisterEmployee", Entidad = emp };
                clientStreamReader = new StreamReader(client.GetStream());
                clientStreamWriter = new StreamWriter(client.GetStream());
                clientStreamWriter.WriteLine(JsonConvert.SerializeObject(empToRegister ));
                clientStreamWriter.Flush();
                serializedRsp = clientStreamReader.ReadLine();
                serverRsp = (JsonConvert.DeserializeObject<SocketMessage<string>>(serializedRsp));
                client.Close();
                return serverRsp;

            } catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                client.Close();
                return new SocketMessage<string> { Entity = "ERROR", Method = ex.Message };
                
            }
        }

标签: c#tcpstreamreadertcplistenertcpserver

解决方案


推荐阅读