2017-06-05 51 views
0

我一直在開發簡單的遠程桌面程序發送,接收服務器,客戶端之間的屏幕圖像和做鼠標控制,鍵盤控制。c#Sokcet編程錯誤的數據

當我試圖發送服務器鼠標X,Y位置到客戶端進行控制時,客戶端收到錯誤的數據。

ex)服務器發送的數據是MouseControl$Position$10(Mouse_X_Position)$10(Mouse_Y_Position)$450(pictureBox.Width)$450(pictureBox.Height)。它首先運行良好,客戶端收到服務器發送的相同數據。但是,幾秒鐘後客戶端收到像ntrol$Position$10(Mouse_X_Position)$10(Mouse_Y_Position)$450(pictureBox.Width)$450(pictureBox.Height)這樣的數據。第一個字MouseControl的某些部分在服務器仍然發送正確數據時消失MouseControl$Position$10(Mouse_X_Position)$10(Mouse_Y_Position)$450(pictureBox.Width)$450(pictureBox.Height)

幫助我擺脫這種麻煩。我想知道它爲什麼會發生 提前謝謝!

這裏是低於

-server 
    private void StartMouseControl() 
    { 
     NetworkStream MouseControlStream = MouseControlDataSock.GetStream(); 
     byte[] buffer = null; 

     while (true) 
     { 
      Point PointXY = pictureBox1.PointToClient(new Point(Control.MousePosition.X, Control.MousePosition.Y)); 
      int MouseX = PointXY.X; 
      int MouseY = PointXY.Y; 

      /* when mouse pointer in pictureBox ... */ 
      if ((MouseX >= 0 && MouseX <= pictureBox1.Width) && (MouseY >= 0 && MouseY <= pictureBox1.Height)) 
      { 
       MouseControlStream.Flush(); 
       buffer = Encoding.Unicode.GetBytes("MouseControl$Postion$" + MouseX.ToString() + "$" + MouseY.ToString() + "$" + pictureBox1.Width.ToString() + "$" + pictureBox1.Height.ToString()); 
       MouseControlStream.Write(buffer, 0, buffer.Length); 
       MouseControlStream.Flush(); 
      } 

      Thread.Sleep(400); 
     } 
    } 




    -client 
    private void StartMouseControl() 
    { 
     int BUFFERSIZE = 72; 
     int read; 
     byte[] buffer = new byte[BUFFERSIZE]; 

     while (MouseControlDataSock.Connected) 
     { 
      /* seperate protocol data from server and save in Sep_message[] */ 
      MouseControlstream = MouseControlDataSock.GetStream(); 

      read = 0; 
      while (read < buffer.Length) 
      { 
       int readbyte = MouseControlstream.Read(buffer, read, buffer.Length - read); 
       if (readbyte == 0) 
       { 
        break; 
       } 
       read += readbyte; 
      } 
      MouseControlstream.Flush(); 

      string message = Encoding.Unicode.GetString(buffer, 0, read); 

      string splitter = "$"; 
      char[] split = splitter.ToArray(); 

      string[] Sep_message = message.Split(split, StringSplitOptions.RemoveEmptyEntries); 

      if (Sep_message[0].Equals("MouseControl")) 
      { 
       if (Sep_message[1].Equals("Postion")) 
       { 
        // Mouse_X_Position, Mouse_Y_Position, pictureBox.Width, pictureBox.Height 
        int MouseX_FromServer = int.Parse(Sep_message[2]); 
        int MouseY_FromServer = int.Parse(Sep_message[3]); 
        int PicBoxWidth_FromServer = int.Parse(Sep_message[4]); 
        int PicBoxHeight_FromServer = int.Parse(Sep_message[5]); 
       } 
      } 

      Thread.Sleep(100); 
     } 
    } 
+0

謝謝你,Pikoh! –

回答

0

我的代碼,你似乎是假設你的數據到達在它是發送相同的單位;這可能與UDP協同工作,但是對於TCP流而言,並不存在這樣的保證 - 如果您啓用了自動緩衝和/或「nagle」,那肯定不會發生。所以:當您從插座有「一些數據」,message可能是(任何):

  • 正好一個消息
  • 一半一條消息
  • 單個字符
  • 一個還有一點點消息
  • 一個消息,17個整個消息,和另一個

以Unicode的情況下開始的端部,它也可能是部分單個字符 - 這就是爲什麼你應該以二進制工作,直到你知道你有一個「框架」,並且只在框架內進行unicode解碼。所以,你還需要考慮:

  • 一個字符,一個完整的角色,與其他角色的一半(零幀)

這是結束你的工作分割TCP流到「幀」(即流內的邏輯消息)。由於這是一個基於文本的協議,換行符將是跟蹤整個消息的明顯方式。這是您的工作,以保持您無法處理的數據的後臺緩衝區 - 即不完整的幀;這應該(如提到)是二進制,除非你知道你只會看到ASCII數據。

+0

謝謝Marc Gravell!正如你所提到的那樣,我將製作邏輯消息並將它們發送到服務器並進行分割,組合完整的幀。 –