2014-08-27 51 views
2

我在收到一次後嘗試第二次讀取時遇到問題。我相信寫入是排隊的,只有當我停止應用程序時纔會通過。不知何故,在第一次閱讀之後,即使在閱讀整個消息之後,我仍然阻止。我的目標是讀取傳入的消息,處理它,然後向連接的客戶端發送消息,然後期望客戶端返回一條消息,確認它收到消息。 這裏是我到目前爲止的代碼TcpClient無法在第二次嘗試時讀取

我開始在一個單獨的線程監聽,等待客戶

 this.tcpListener = new TcpListener(IPAddress.Loopback, 14000); 
     this.listenThread = new Thread(new ThreadStart(ListenForClients)); 
     this.listenThread.Start(); 

話後,客戶端已連接我扔通信的處理在另一個線程

 this.tcpListener.Start(); 
     tcpClient = this.tcpListener.AcceptTcpClient(); 
     Thread clientThread = new Thread(new ParameterizedThreadStart(ProcessMessage)); 
     clientThread.Start(tcpClient); 

的ProcessMessage的方法看起來像follwing

public void ProcessMessage(object client) 
    { 
     if (client != null) 
     { 
      tcpClient = client as TcpClient; 
     } 

     this.messageReceived = false; 

     NetworkStream clientReadStream = tcpClient.GetStream(); 


     byte[] message = new byte[tcpClient.ReceiveBufferSize]; 
     int byteRead = 0; 

     while (!this.messageReceived) 
     { 
      byteRead = 0; 
      if (tcpClient.Connected) 
      { 
       try 
       { 
        byteRead = clientReadStream.Read(message, 0, tcpClient.ReceiveBufferSize); 
       } 
       catch (Exception) 
       { 
        throw; 
       } 

       if (byteRead == 0) 
       { 

        break; 
       } 
       else 
       { 
        System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); 
        this.request = encoder.GetString(message, 0, byteRead); 
        if (!string.IsNullOrEmpty(this.request)) 
        { 
         this.messageReceived = true; 
        } 

       } 
      } 
     } 
    } 

處理消息,然後我要求將消息發送回客戶端後,我這樣做,從通過一個稱爲送出數據

public void SendData(string data) 
     { 
      if (tcpClient != null) 
      { 

       if (tcpClient.Connected) 
       { 
        try 
        { 
         System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); 
         NetworkStream clientWriteStream = tcpClient.GetStream(); 

         byte[] buffer = encoder.GetBytes(data); 
         clientWriteStream.Write(buffer, 0, buffer.Length); 
         clientWriteStream.Flush(); 

         this.messageReceived = false; 

        } 
        catch 
        { 
         throw; 
        } 
       } 
      } 

     } 

不知道哪個方向看..方法不同的線程謝謝你的任何建議或方向提前

+1

這是期待TCP處理_messages_的經典案例? TCP保證在連接的一端推送的字節將以相同的順序退出另一端,且不會重複。沒有消息的概念。你是否檢查過你的緩衝區,看看你一次沒有收到更多或更少的信息? – HABO 2014-08-28 00:39:36

+0

在這種特殊情況下,我們試圖在兩個實體之間傳遞xml。來回通信一次只進行一個階段,並且一次僅與一個客戶進行。所以我可以假設一個電話來了,除非我寫(發送)另一個電話,否則沒有別的東西會來。 – crossroad 2014-08-28 00:47:53

+1

@crossroad:你誤解了評論。關鍵是你不能知道XML數據將在一次讀取中到達。可能需要多次讀取來獲取完整的xml消息。我有一篇關於這個主題的博客文章(http://blog.stephencleary.com/2009/04/message-framing.html)。 – 2014-08-28 00:58:25

回答

1

你正在設置this.messageReceived = true;當你有recive消息,而condation是同時,當第一條消息recived這是監守,找你recive而將終止...

試試這個代碼(this.messageReceived!):

public void ProcessMessage(object client) 
{ 
    if (client != null) 
    { 
     tcpClient = client as TcpClient; 
    } 

    this.messageReceived = false; 

    NetworkStream clientReadStream = tcpClient.GetStream(); 


    byte[] message = new byte[tcpClient.ReceiveBufferSize]; 
    int byteRead = 0; 

    while (true) 
    { 
     byteRead = 0; 
     if (tcpClient.Connected) 
     { 
      try 
      { 
       byteRead = clientReadStream.Read(message, 0, tcpClient.ReceiveBufferSize); 
      } 
      catch (Exception) 
      { 
       throw; 
      } 

      if (byteRead == 0) 
      { 

       break; 
      } 
      else 
      { 
       System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); 
       this.request = encoder.GetString(message, 0, byteRead); 
       if (!string.IsNullOrEmpty(this.request)) 
       { 
        this.messageReceived = true; 
       } 

      } 
     } 
    } 
} 

和來自這部分代碼小心:

if (byteRead == 0) 
    { 

     break; 
    } 
    else ... 

因爲如果Read方法劑量不讀任何東西,而再次將終止......

相關問題