TcpClient – 远程主机强制关闭现有连接

信息

我一直在用c#开发一个web http服务器,并决定添加一个远程控制台function。 控制台可以在任何位置使用,并使用TcpListener(Web服务器)和TcpClient(远程控制台)来发送命令和function。

代码

这就是我的服务器的样子:

TcpListener consoleListener = new TcpListener(consolePort); consoleListener.Start(); byte[] bytes = new Byte[256]; string data = null; while (true) { TcpClient client = consoleListener.AcceptTcpClient(); data = null; byte[] msg = { 0 }; int i; while ((i = client.GetStream().Read(bytes, 0, bytes.Length)) != 0) { data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); if (data == "shutdown") { //Server shutdown logic. } //Other commands here... else { msg = Encoding.ASCII.GetBytes("Invalid command. Type 'help' or '?' to get a list of commands."); } client.GetStream().Write(msg, 0, msg.Length); //sends return message to console } client.Close(); //closes connection between client and server after EVERY command. Connection is reopened when a new command is sent. } 

注 – 服务器在Web服务器和主控制台应用程序线程的单独线程上运行。

这是我的客户:

 public static string Communicate(string text) { try { TcpClient client = new TcpClient(ip, port); //initializes tcpclient (ip and port are correct) byte[] data = System.Text.Encoding.ASCII.GetBytes(text); //converts text to bytes for stream writing NetworkStream stream = client.GetStream(); stream.Write(data, 0, data.Length); Console.WriteLine("Sent data: " + text); data = new Byte[256]; string responseData = String.Empty; //initializes responsData string Int32 bytes = stream.Read(data, 0, data.Length); responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); client.Close(); return responseData; //returns what server writes } catch (Exception ex) { return "An error occured\n" + ex.ToString(); } } 

问题

我可以通过成功返回向服务器发送一个命令。 但是,当我尝试发送另一个命令时,服务器会抛出以下错误:

 System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) at ---.Server.ConsoleListener() in X:\Users\---\Documents\Visual Studio 2013\Projects\---\---\Program.cs:line x 

我知道这不是防火墙或管理员提升问题,因为我可以成功发送一个命令。 只有在发送的第二个命令上才会抛出此错误。

这是描述问题的屏幕截图: 远程控制台和服务器通信和错误报告。

编辑:通过一些研究,我发现问题很可能是我的for循环中的一个小错误的结果。 但是,我不知道如何解决这个问题,因为我不知道确切的问题:)。 请帮我识别它,以便我可以解决它。

再次感谢

您的客户端似乎在一条消息后关闭了连接。

 responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); client.Close(); return responseData; //returns what server writes 

如果要保持连接,则应在客户端上创建一个类似于服务器上的循环。 如果您希望每次在服务器上优雅地关闭流时建立新连接,而不是像这样的循环。 如果消息较长或者您需要为命令指定最大长度,您仍需要循环。

我不知道你是否修复了你的问题,但我想你应该至少发布你的解决方法,以便其他人可以检查它。

我不完全理解你的问题,但我有同样的例外,但是在客户端断开连接并且服务器试图读取流(networkStream)时触发了我的。

我只有一个阅读命令

 networkstream.Read(mybuffer, 0, mybuffer.length); 

如检查答案所示我改为:

 do { byte[] buff = new byte[1]; networkstream.Read(buff, 0, 1); myreceivedbuff.Add(buff); } while (networkstream.DataAvailable) 

这也产生了客户端光盘的问题,所以我不得不这样做

 do { byte[] buff = new byte[1]; try { networkstream.Read(buff, 0, 1); } catch(exception ex) { throw new exception("The dam client disconnected in the middle of a transaction."); } myreceivedbuff.Add(buff); } while (networksteam.DataAvailable) 

我不得不这样做,因为它在客户端或服务器上的exception是无关紧要的。 主机断开连接同时我的例外是CLIENT断开连接,这个通用消息误导我解决方案。

很抱歉,如果代码没有从vs粘贴,但我输入了这里,所以修复大小写,以便它可以编译。

希望这有助于某人。