2012-11-09 82 views
0

我在WP7中使用TCP客戶端。目前我只是使用MSDN的示例代碼,所以它應該可以工作。但由於某種原因,這種特殊的反應正在被縮短。TCP響應中斷

應該REPLY(隨後很多空字節,從緩衝器):

202-多行響應如下\ r \ ntimestamp = 00000000校驗= 00000000 \ r \ n名稱= \「FLASH:閃存\ xshell.xex \「\ r \ n \ r \ n

但是,相反它的返回(並且沒有任何尾隨的空字節):

202-多響應如下\ r \ n

我爲獲得來自TCP服務器的響應代碼:

 try 
     { 
      if (!_isConnected) 
       Connect(); 
      if (!_isConnected) 
       return null; 

      SendTextCommand(command); 

      string response = ""; 

      SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); 
      socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint; 
      socketEventArg.UserToken = null; 

      socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE); 

      socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) 
      { 
       if (e.SocketError == SocketError.Success) 
       { 
        response = Encoding.ASCII.GetString(e.Buffer); 
        response = response.Trim('\0'); 
       } 
       else 
        throw new Exception(e.SocketError.ToString()); 

       _pausingThread.Set(); 
      }); 

      _pausingThread.Reset(); 
      _socket.ReceiveAsync(socketEventArg); 
      _pausingThread.WaitOne(TIMEOUT_MILLISECONDS); 

      return response; 
     } 
     catch (Exception ex) { GenerateException(ex.Message); return "123"; } 
+0

我不確定,但我認爲有時緩衝區在讀取它之前並不保存所有的數據。嘗試使用Thread.Sleep(100);或者等待一下,看看它是否會有完整的字符串。另外,MAX_BUFFER_SIZE有多少,是否足夠? –

+0

是的,如果我再次調用函數,它會返回更多的輸出字符串。 MAX_BUFFER_SIZE是(3 * 1024),因此它足夠大。你會建議把Thread.Sleep放在哪裏? –

+0

在讀取Buffer之前,如果(e.SocketError == SocketError.Success)將它放在這行之後,我知道這是一個糟糕的解決方案,但您無法控制網絡和協議堆棧的其他層的速度。這種情況一直在發生,所以你將不得不爲這種情況調整你的程序邏輯(即在字符串的末尾添加一些特殊字符,因此在TCP/IP協議上實現你自己的協議)。 –

回答

1

爲了解決這個問題,你必須檢查響應是多行。如果是,則循環直到完成「。\ r \ n」。否則,你只讀一次,你就完成了。像這樣:

public string GetFromTextCommand(string command) 
    { 
     try 
     { 
      if (!_isConnected) 
       Connect(); 
      if (!_isConnected) 
       return null; 

      SendTextCommand(command); 

      string response = GetFromTextCommand(); 

      if (response.StartsWith("202")) 
      { 
       while (!response.EndsWith(".\r\n")) 
       { 
        string newResponse = GetFromTextCommand(); 

        response += newResponse; 
       } 
      } 

      return response; 
     } 
     catch (Exception ex) { GenerateException(ex.Message); return null; } 
    } 
    public string GetFromTextCommand() 
    { 
     try 
     { 
      if (!_isConnected) 
       Connect(); 
      if (!_isConnected) 
       return null; 

      string response = ""; 

      SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); 
      socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint; 
      socketEventArg.UserToken = null; 

      socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE); 

      socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) 
      { 
       if (e.SocketError == SocketError.Success) 
       { 
        response = Encoding.ASCII.GetString(e.Buffer); 
        response = response.Trim('\0'); 
       } 
       else 
        throw new Exception(e.SocketError.ToString()); 

       _pausingThread.Set(); 
      }); 

      _pausingThread.Reset(); 
      _socket.ReceiveAsync(socketEventArg); 
      _pausingThread.WaitOne(TIMEOUT_MILLISECONDS); 

      return response; 
     } 
     catch (Exception ex) { GenerateException(ex.Message); return null; } 
    }