2014-07-15 41 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

相關問題