最近在研究socket传输文件,由于项目需求,采用的是二进制读取文件,分割成若干包,加上其他信息和起始、结束标志后发送。接收以后先解析再拼接。但是在测试中问题就来了,首先是发送了1000个包,结果接收了1200多个包,研究以后发现这是因为socket 的tcp协议粘包,这个问题解决了。
然后就是接收了5个包以后,就不解析了。代码如下:
if (buffer.Count < 34)
{
readlength = 0;
return null;
}
//查找\r\n标记符
for (int i = buffer.Offset, len = buffer.Offset + buffer.Count; i < len; i++)
{
if (buffer.Array[i] == 42 && i + 36 < len && buffer.Array[i + 1] == 35)
{
//ArraySegment<byte> lidarcodeposbytes = new ArraySegment<byte>(buffer.Array, 0, 4);
int lidarcodepos = BitConverter.ToInt32(buffer.Array, 2);
int filenamepos = BitConverter.ToInt32(buffer.Array, 6);
int filestreampos = BitConverter.ToInt32(buffer.Array, 10);
long TotalFileBytesLength = BitConverter.ToInt64(buffer.Array, 14);
int CurPackage = BitConverter.ToInt32(buffer.Array, 22);
int TotalPackages = BitConverter.ToInt32(buffer.Array, 26);
int bodylength = BitConverter.ToInt32(buffer.Array, 30);
for (int j = i + 34; j < len; j++)
{
if (buffer.Array[j] == 35 && (j + 1) < len && buffer.Array[j + 1] == 42)
{
Console.WriteLine(CurPackage + "\t" + buffer.Count.ToString());
if (lidarcodepos > filenamepos || filenamepos > filestreampos)
{
readlength = 0;
return null;
}
debug发现,buffer的count是在不断增加的,每次增加的数量就是每次发送的字节数,再进一步分析,就是
if (buffer.Array[j] == 35 && (j + 1) < len && buffer.Array[j + 1] == 42)
没有进去,这里是一条消息结束的标识符,两个字节,用过好几种,比如“CK”,“*#”等,最终发现,这些标识符的字节在图片中都存在,所以没有进一步解析,换了一个文本文件就没问题了,所以标识符如何设置也是一门学问