2014-07-15 42 views
3

的信息的TcpClient - 一个现有的连接被强行远程主机

我一直在开发C#中的网页http服务器,并决定添加远程控制台功能关闭。控制台可以在任何位置使用,并使用TcpListener(Web服务器)和TcpClient(远程控制台)来发送命令和函数。

守则

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

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. 
} 

注 - 服务器在一个单独的线程上运行的网络服务器和主控制台应用程序线程两者。

这是我的客户:

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 

我知道这是不是防火墙或管理员海拔问题,我可以通过成功地发送一个命令。只有在发送第二个命令时才会抛出此错误。

这里是描述问题的屏幕截图: The remote console and server communication and error reporting.

编辑:这样做了一些研究,我发现这个问题是最有可能的一个小错误,在我的for循环的结果。但是,我不知道解决这个问题的任何方法,因为我不知道确切的问题:)。请帮助我确定它,以便我可以修复它。

再次感谢

+0

作为便笺:TCP并不保证您将在一次读取中获得*,例如“关闭”*。它可能被分成*“关闭”*和*“下”*。 – EZI

+0

@EZI感谢您的提示 - 我会马上更新! – rodit

+0

@EZI我应该如何实现 - 对不起 – rodit

回答

4

看来您的客户端在一封邮件后关闭连接。

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

如果你想保持连接,你应该在客户端上有一个类似于你在服务器上的循环。如果你想建立新的连接,每次你应该在服务器上优雅地关闭流并且没有像这样的循环。如果消息较长,或者您需要指定命令的最大长度,则仍然需要循环。

+0

感谢您的帮助。虽然这并没有解决我的问题,但是你让我搞砸了我的代码,足以认识到我必须以不同的方式做到这一点:)所以非常感谢!因此,你会得到一个大绿剔! – rodit

+6

@rodit一个“绿色勾号”(接受答案)不应该是对那些帮助过你的人的奖励,如果他们没有回答你问的问题。 –

+0

@KennyEvitt指出 - 谢谢你的提示:) – rodit

3

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

我不完全理解你的问题,但我有同样的例外,但我的客户端断开连接,并且服务器试图读取流(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) 

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

对不起,如果代码不是从vs粘贴,但我在这里键入,所以修正大写,以便它可以编译。

希望这可以帮助别人。

+0

我面临同样的问题.. – SANDEEP

相关问题