I have a part of code about Send and Receive use Network stream. I send two packages thought socket but Receive method receive one package and it contains two packages . I don't know why. help me please.
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
{
}
}
Send method. I sent 2 package but receive method receive one.
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
{
}
}
TCP is a stream protocol. You don't send "packages" - you send a stream of data, and receive a stream of data. The fact that the data is broken up into packets behind the scenes is a low-level implementation detail of the NetworkStream
that you're using.
If you need to package your data up, you'll have to do so yourself. Typically that involves adding some sort of header - the simplest form is just the length of the data - followed by the data. The reading side then reads the header, and knows how much data is in the message.
See more on this question at Stackoverflow