如题。对方发过来的数据包的长度不固定,有时候108字节,有时候180字节,有时候36字节,有时候。。
以前数据包长度固定的时候,我定义的接收字节数据为
private static byte[] byteAll = new byte[198];
private static byte[] crc = new byte[4];
代码是
socket.Bind(iep);
socket.Listen(150);
newSocket = socket.Accept();
while (true)
{
newSocket.Receive(byteAll);
Array.Copy(byteAll, 0, bytes, 0, 194);
Array.Copy(byteAll, 8, crc, 0, 4);
...........现在发送过来的包长度不固定,我也不知道怎么定义接收时候的字节数组长度了,截取的时候也不知道从哪里开始截取了,怎么办呢。
谢谢,在线等。
以前数据包长度固定的时候,我定义的接收字节数据为
private static byte[] byteAll = new byte[198];
private static byte[] crc = new byte[4];
代码是
socket.Bind(iep);
socket.Listen(150);
newSocket = socket.Accept();
while (true)
{
newSocket.Receive(byteAll);
Array.Copy(byteAll, 0, bytes, 0, 194);
Array.Copy(byteAll, 8, crc, 0, 4);
...........现在发送过来的包长度不固定,我也不知道怎么定义接收时候的字节数组长度了,截取的时候也不知道从哪里开始截取了,怎么办呢。
谢谢,在线等。
http://blog.csdn.net/jq_whh/article/details/6560711
此类问题LZ并未想清楚到底是为什么会时而长度108,时而长度180。
为什么会出现这种长度不固定的情况,那是因为网络问题。
接收不定长度的数据包是需要有一个包头的,前4字节是整个数据包的长度描述。这个是发送端自定义的协议。
public override ReplyMessage Read(Stream stream)
{
ReplyMessage reply = new ReplyMessage(); byte[] nFileLenBytes = new byte[4];
stream.Read(nFileLenBytes, 0, nFileLenBytes.Length);
int len = BitConverter.ToInt32(nFileLenBytes, 0);
reply.Length = len; byte[] buffer = new byte[0]; while (len > 0 && stream.CanRead)
{
byte[] readBytes = new byte[102400];
int recv = stream.Read(readBytes, 0, readBytes.Length);
len -= recv; if (recv < 102400)
{
//小于指定长度的包,根据接收的实际长度清除空字节。
byte[] m_readBytes = new byte[recv];
System.Buffer.BlockCopy(readBytes, 0, m_readBytes, 0, recv);
readBytes = m_readBytes;
}
int newLen = buffer.Length + readBytes.Length;
byte[] newBuffer = new byte[newLen];
System.Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length);
System.Buffer.BlockCopy(readBytes, 0, newBuffer, buffer.Length, recv);
buffer = newBuffer; System.Threading.Thread.Sleep(1);
}
reply.Buffer = buffer; return reply;
}
发过来的数据包是这样的,包括数据包长度
指令状态 :STATUS1 = 0xBB
设备地址 :假设为 0xC6 0x83 0x6E 0x70
数据包长度:0x00 0xC6
DATA1 ~ 180
校验码 :0xD6 0x72 0x48 0xF8
具体数据如下:
0x5A 0xA5 0x69 0x96 0xBB 0x00 0x00 0x00 0xC6 0x83
0x6E 0x70 0x00 0xC6 0x02 0x37 0x37 0x20 0x33 0x39
0x20 0x2d 0x37 0x31 0x20 0x34 0x36 0x30 0x30 0x30
0x20 0x32 0x35 0x30 0x32 0x20 0x34 0x34 0x36 0x44
0x20 0x37 0x20 0x33 0x20 0x33 0x33 0x20 0x2d 0x39
0x36 0x20 0x32 0x35 0x20 0x20 0x20 0x20 0x20 0x03
0x45 0x52 0x52 0x4f 0x52 0x20 0x43 0x4f 0x44 0x45
0x3a 0x20 0x30 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x20 0x07 0x45 0x52 0x52 0x4f 0x52
0x20 0x43 0x4f 0x44 0x45 0x3a 0x20 0x30 0x20 0x20
0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x0C
0x37 0x37 0x20 0x34 0x30 0x20 0x2d 0x37 0x30 0x20
0x34 0x36 0x30 0x30 0x30 0x20 0x32 0x35 0x30 0x32
0x20 0x34 0x34 0x36 0x44 0x20 0x37 0x20 0x33 0x20
0x33 0x33 0x20 0x2d 0x39 0x36 0x20 0x32 0x36 0x20
0x20 0x20 0x20 0x20 0xD6 0x72 0x48 0xF8
除了第一个表示编号5,其它当文本显示就是:762 36 -74 46000 2502 5A43 4 1 30 -103 29 这个是怎么转换的呢
这应该是数据包起始标识:0x5A 0xA5 0x69 0x96
指令状态 :STATUS1 = 0xBB
保留:0x00 0x00 0x00
设备地址 :0xC6 0x83 0x6E 0x70
数据包长度:0x00 0xC6
数据:后面读取0x00c6个字节
校验:
后面就是第二个数据包,再搜索0x5A 0xA5 0x69 0x96就可以了
如果遇到上面的这种情况,可以把数据丢弃,准备搜索起始标识。
那接收的byte[]长度定义为多少呢。以前数据包长度固定的时候,我定义的接收字节数据为
private static byte[] byteAll = new byte[198];
完全占满,现在他不固定,定义多少字节长度呢,定义多了有空字节,定义少了接收不完
1、把接收到的数据全部放到一个先入先出堆栈
2、从堆栈中读取数据包,
通常把数据包格式定义成一个类,每个字段作为一个成员变量,根据数据包的实际数据填写,
byteAll 可以根据长度字段来定义