2011-09-22 163 views
0

我有一個快速和骯髒的問題。因此,我有兩個客戶端和一個服務器運行。我可以毫無問題地將來自客戶端的消息傳達給服務器。當我想從客戶端讀取兩條消息時出現問題 - 而不僅僅是一條消息。發送服務器多條消息? C#

我收到的錯誤是:IOException未處理。無法從傳輸連接讀取數據:現有連接被遠程主機強制關閉。

這是我在服務器端代碼:

私有靜態無效HandleClientComm(對象客戶端) { /**創建包含DatabaseFile對象**/ 名單theDatabase =新名單()的列表;

 TcpClient tcpClient = (TcpClient)client; 
     NetworkStream clientStream = tcpClient.GetStream(); 

     byte[] message = new byte[4096]; 
     int bytesRead; 

     do 
     { 
      bytesRead = 0; 

      try 
      { 
       // Blocks until a client sends a message      
       bytesRead = clientStream.Read(message, 0, 4096); 
      } 
      catch (Exception) 
      { 
       // A socket error has occured 
       break; 
      } 

      if (bytesRead == 0) 
      { 
       // The client has disconnected from the server 
       break; 
      } 

      // Message has successfully been received 
      ASCIIEncoding encoder = new ASCIIEncoding(); 

      Console.WriteLine("To: " + tcpClient.Client.LocalEndPoint); 
      Console.WriteLine("From: " + tcpClient.Client.RemoteEndPoint); 
      Console.WriteLine(encoder.GetString(message, 0, bytesRead)); 


      if (encoder.GetString(message, 0, bytesRead) == "OptionOneInsert") 
      { 
       byte[] message2 = new byte[4096]; 
       int bytesRead2 = 0; 

       **bytesRead2 = clientStream.Read(message, 0, 4096);** //ERROR occurs here! 

       Console.WriteLine("Attempting to go inside insert)"); 
       Menu.Insert(theDatabase, bytesRead2); 
      } 

這裏是我的客戶端代碼:

 ASCIIEncoding encoder = new ASCIIEncoding(); 
     byte[] buffer = encoder.GetBytes("OptionOneInsert"); 

     Console.ReadLine(); 
     clientStream.Write(buffer, 0, buffer.Length); 
     clientStream.Flush(); 

     NetworkStream clientStream2 = client.GetStream(); 
     String text = System.IO.File.ReadAllText("FirstNames.txt"); 
     clientStream2.Write(buffer, 0, buffer.Length); 
     clientStream2.Flush(); 
     ASCIIEncoding encoder2 = new ASCIIEncoding(); 

     byte[] buffer2 = encoder2.GetBytes(text); 
     Console.WriteLine("buffer is filled with content"); 
     Console.ReadLine(); 

當客戶端發送消息「optionOne」,它是由服務器就好了好評。只有當我試圖發送名爲「文本」的字符串時,問題纔會出現!

任何幫助將不勝感激 - 我不是那麼熟悉的插座,因此,我一直在試圖與現在明白這一點了一段

+0

你能給我們多一點服務器端代碼嗎? –

+0

另外,你可以發佈哪一行代碼拋出異常? – wllmsaccnt

+1

沒有任何跡象表明你在'OptionOneInsert'之後向服務器發送任何東西 - 你沒有使用* clientStream2'。 –

回答

3

你已經有了一個問題就在這裏掙扎 - 沒有什麼可以指定一條消息的結束和另一條消息的開始。服務器很可能會一次收到兩條消息,或者一條消息,然後是另一條消息。

避免這種情況的最簡單方法是在每個消息前加上其中的字節數,例如,作爲固定的四字節格式。因此,要發送消息,你會:

  • 從字符串字節編碼它(最好使用UTF-8,而不是ASCII除非你確信你將永遠不會需要任何非ASCII文本)
  • 寫出字節數組的長度爲四字節的值
  • 寫出內容

在服務器上:

  • 讀四個字節(循環如有必要 - 有沒有保證,你甚至會閱讀這些四個字節在一起,雖然你幾乎肯定會)
  • 轉換的四個字節轉換成整數
  • 分配該大小
  • 的字節數組
  • 循環輪,從「當前位置」到緩衝區的末尾讀,直到你填寫的緩衝區
  • 轉換緩衝成一個字符串

另一種方法就是使用BinaryReaderBinaryWriter - ReadStringWriteString使用長度前綴,當然,以一種稍微不同的形式。

另一種選擇,你可能使用是有一個分隔符(如回車),但是這意味着你將需要添加轉義如果你需要在將文本分隔符。

+0

我看,好的,這是有幫助的。我讓我的程序停止崩潰。但正如你所表示的那樣,第二條消息還沒有完全收到。非常感謝你的回覆! – BigBug

+0

我不認爲我會再次嘗試回答一個C#問題。與你的相比,我的礦難將不完全 –

+0

@Bojan Kogoj:根本不用擔心。我真誠感謝任何幫助。 C#沒問題。有很多不同的方法來做不同的事情。所以,我希望你仍然願意幫助別人:o) – BigBug

相關問題