阻塞模式下WSARecv接收较大数据时,WSARecv并不一定会等到接收到指定大小的消息后再返回,而是接收到一定量数据了也会强制返回。例如:
WSABUF DataBuf;
DataBuf.buf = new char[1024 * 10];
DataBuf.len = 4096;
DWORD RecvBytes, Flags = 0;
int rs = WSARecv(socket, &DataBuf, 1, &RecvBytes, &Flags, NULL, NULL);
这里可能不会等到接收到4096个字节后返回,可能接受3000个字节就会返回,及时设置了接收延迟和接受缓冲区大小,也不起作用,我想这个setsockopt方法是不是只对recv有效(setsockopt貌似是winsock1.1的函数),这个很奇怪,知道原因所在的希望各位帮忙解答下
//发送缓冲区
int nSendBuf = 64*1024;
setsockopt(conn_socket, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));
//设置接收超时(对WSARecv不起作用,只对阻塞式recv起作用)
int nNetTimeout = 3000;//3秒,
setsockopt(conn_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, sizeof(int));
这样只能自己写逻辑做保护:
WSABUF DataBuf;
DataBuf.buf = recv_buf;
DWORD RecvBytes, Flags;
bool setLen = true;
while(true)
{
if(setLen)
{
DataBuf.buf = recv_buf;
DataBuf.len = 4096;
}
RecvBytes = 0;
Flags = 0;
rs = ::WSARecv(bingo_net->GetSocket(), &DataBuf, 1, &RecvBytes, &Flags, NULL, NULL);
if(RecvBytes < DataBuf.len)
{
DataBuf.buf += RecvBytes;
DataBuf.len -= RecvBytes;
setLen = false;
continue;
}
setLen = true;
//...
//拿到一帧消息后从DataBuf取走相应的数据
}
想大家请教,这是什么原因?