日期:2014-05-19  浏览次数:20866 次

问关于socket收发包的问题以及结束判断的问题。
一个客户端接受包,一个服务器端不停的发包,比如一次发1K。
我客户端用socket收的时候,存放的数组也是定义的1k大小
如:
byte[]   buffer   =   new   byte[1024];
socket.receive(buffer);

现在问题是他有时候收到的只有一部分,剩下一部分是下一次收才能收到?
这是不是我收的时候服务器端还没有完全发完1个包啊?必须循环收才能确保收完?
还有就是如果必须循环收那我怎么区分每个包呢?每个包最后虽然是有一个结束标记,但是我要挨个字节去比对吗?这样效率是不是太低了?

------解决方案--------------------
在包的开头加一个开始的标记
紧跟着再加上包的长度
然后根据这个长度收包
也就是说你定一个协议,就是定好包的格式。
------解决方案--------------------
根据个长度收包
也就是说你要用这个Receive来收包
public int Receive (
byte[] buffer,
int size,
SocketFlags socketFlags
)

参数
buffer
Byte 类型的数组,它是存储接收到的数据的位置。

size
要接收的字节数。

socketFlags
SocketFlags 值的按位组合。


------解决方案--------------------
一般情况下,接收缓冲最好大于发送缓冲,因为在发送包中还有校验码等数据,至于什么接收完一个包,这点你不用担心,socket会自己判断的,你只要把tcp缓冲中的数据及时处理了就可以了,你可以参看msdn中的例子,同步和异步的都看看吧。
------解决方案--------------------
原理是 现接收1024字节
基本上这1024内已经包括头信息了,
读取里面的 Content-Length: 888
然后根据这个长度,就知道下面继续读多少了

循环开线程接收
Socket client;
int recvCount;
int availCount;
int income = 0;
byte[] recvBytes = new byte[8*1024];
do
{
availCount = client.Available;

if (income == 0)
{
income++;
continue;
}
if (availCount <= 0 && income> 0)
break;

if (availCount < 8*1024)
{
recvCount = client.Receive(recvBytes, availCount, SocketFlags.None);
}
else
{
recvCount = client.Receive(recvBytes, recvBytes.Length, SocketFlags.None);
}

income++;
data += Encoding.UTF8.GetString(recvBytes, 0, recvCount);

}
while (availCount > 0);