2014-11-05 4 views
0

보내기 및 받기 네트워크 스트림에 관한 코드가 있습니다. 나는 두 개의 패키지를 socket으로 생각하지만 Receive 메소드는 하나의 패키지를 받고 두 개의 패키지를 포함한다. 나는 이유를 모른다. 도와주세요, 제발.TcpClient의 NetworkStream이 각 패키지를 수신하지 못합니다.

private void ClientReceive() 
    { 
     try 
     { 
      DataPackage pakage = null; 
      byte[] buffer = null; 
      byte[] temp = null; 
      int receivebytes = 0; 
      while (true) 
      { 
       Thread.Sleep(500); 
       buffer = new byte[1024]; 
       receivebytes = this.m_stream.Read(buffer, 0, buffer.Length); //bug only receive one package but it contains 2 package, which is sent via "Send" method 
       this.m_stream.Flush(); 
       if (receivebytes == 0) 
       { 
        this.IsExit = true; 
        if (this.OnClientExit != null) 
        { 
         this.OnClientExit(this, new ClientExitAvgs(this.ClientInfo, ShutdownType.Shutdown)); 
        } 
        this.StopClient(); 
        break; 
       } 
       temp = new byte[receivebytes]; 
       Array.Copy(buffer, temp, receivebytes); 
       pakage = new DataPackage(); 
       pakage.DataHeader(temp); 
       switch (pakage.Cmd) 
       { 
        case Command.Shutdown: // client shutdown or application close 
         buffer = new byte[4]; 
         this.m_stream.Read(buffer, 0, buffer.Length); 
         this.m_stream.Flush(); 
         ShutdownType downType = (ShutdownType)BitConverter.ToInt32(buffer, 0); 
         if (OnClientExit != null) 
         { 
          OnClientExit(this, new ClientExitAvgs(this.ClientInfo, downType)); 
         } 
         break; 
        case Command.Name: 
         buffer = new byte[pakage.DataLength]; 
         this.m_stream.Read(buffer, 0, buffer.Length); 
         this.m_stream.Flush(); 
         string regex = Encoding.Unicode.GetString(buffer); 
         this.ClientInfo = ComputerInfo.GetComputerInfo(regex); 
         this.IsReceiveClientInfo = true; 
         break; 
        case Command.USB: 
         buffer = new byte[4]; 
         this.m_stream.Read(buffer, 0, 4); 
         this.m_stream.Flush(); 
         UsbType type = (UsbType)BitConverter.ToInt32(buffer, 0); 
         UsbAvgs e = new UsbAvgs(); 
         e.ClientInfo = this.ClientInfo; 
         e.Usbtype = type; 
         switch (type) 
         {         
          case UsbType.NotRegister:  //connected and not register 

           break; 
          case UsbType.Registered:   // register for usb device 
           break; 
          case UsbType.Remove:    // usb device removed 
           break; 
          case UsbType.Connected:   // usb device connected and registered 
           break; 
         } 
         if (this.OnUsbExecute != null) 
         { 
          this.OnUsbExecute(this, e); 
         } 
         break; 
       } 
      } 
     } 
     catch 
     { 

     } 
    } 

송신 방법. 나는 2 패키지를 보냈지 만 수신 방법은 하나를 받았다.

private void ClientSend() 
    { 
     try 
     { 
      DataPackage pakage = null; 
      byte[] buffer = null; 
      while (true) 
      { 
       Thread.Sleep(500); 
       while (this.SendQueue.Count > 0) 
       { 
        pakage = new DataPackage(); 
        pakage = (DataPackage)this.SendQueue.Dequeue(); 
        //send command 
        buffer = package.ToBytesHeader(); 
        this.m_stream.Write(buffer, 0, buffer.Length); 
        this.m_stream.Flush(); // send first package 
        //Thread.Sleep(10); 
        switch (pakage.Cmd) 
        { 
         case Command.Name: 
          //send computer name 
          buffer = Encoding.Unicode.GetBytes(ComputerInfo.Regex()); 
          this.m_stream.Write(buffer, 0, buffer.Length); //send second package 
          this.m_stream.Flush(); 
          break; 
         case Command.USB: 
          while (this.SendQueue.Count == 0) { } 
          UsbType type = (UsbType)this.SendQueue.Dequeue(); 
          buffer = null; 
          buffer = BitConverter.GetBytes((int)type); 
          this.m_stream.Write(buffer, 0, buffer.Length); 
          this.m_stream.Flush(); 
          break; 
         case Command.Shutdown: 
          while (this.SendQueue.Count == 0) { } 
          buffer = BitConverter.GetBytes((int)(ShutdownType)this.SendQueue.Dequeue()); 
          this.m_stream.Write(buffer, 0, buffer.Length); 
          this.m_stream.Flush(); 
          break; 
        } 
       } 
      } 
     } 
     catch 
     { 

     } 
    } 

답변

2

스트림 프로토콜입니다. "패키지"를 보내지 마십시오 - 데이터 스트림을 보내고 일련의 데이터를 수신합니다. 데이터가 장면 뒤에서 패킷으로 나눠진다는 사실은 사용중인 NetworkStream의 저수준 구현 세부 사항입니다.

데이터를 패키지화해야하는 경우 직접해야합니다. 일반적으로 헤더에는 일종의 헤더를 추가하는 것이 포함됩니다. 가장 간단한 형식은 데이터의 길이이며 데이터 다음에 오는 것입니다. 그런 다음 읽기 측면에서 헤더를 읽고 메시지에있는 데이터의 양을 압니다.

+0

안녕하세요. 귀하의 anwser에 감사드립니다. 나는 그 단어를 잘못 사용한다. "패키지"는 데이터를 의미한다. 내가 물어보고 싶은 : syschronous에서 보내려면받을 수 있습니다. 내 문제는, 먼저 : 나는 4 바이트를 보내고 다음은 4 바이트를 연속적으로 보내지 만 8 바이트를 받는다. 나는 4 바이트를 받고 연속적으로 4 바이트를 받기를 원한다. 미안해, 내 영어 실력이 좋지 않아. –

+0

@HungLe : 한 번에 4 바이트 씩 읽는다. (단,'Read'에 대한 한 번의 호출로 모든 4 바이트를 확실히 읽지는 않는다.) –