[b]阻塞socket是这样的[/b]
去网卡缓冲区读取socket1的数据,读到的数据保存到buf
如果网卡缓冲区有1个字节,就返回1个,有两个就返回两个,当然不能超过length
如果网卡缓冲区没有数据,那么就一直等待,直到有数据可读
是的,很傻很执着 :)
如果客户端再也不发送数据过来,那么就永远的等下去,这显然不够灵活
可以通过
设置等待时间
如果超过了这个等待时间,还没有收到数据就不等了,函数就返回
[b]非阻塞socket是这样的[/b]
调用函数
设置为非阻塞
然后调用
这儿的执行方式为:去查看网卡缓冲区有无数据,如果有那么读取数据并返回,[color=red]如果没有不等待直接返回。[/color]这儿就是与阻塞socket的不同
非阻塞socket的数据读取方式:
recv(socket1, buf, length);
去网卡缓冲区读取socket1的数据,读到的数据保存到buf
如果网卡缓冲区有1个字节,就返回1个,有两个就返回两个,当然不能超过length
如果网卡缓冲区没有数据,那么就一直等待,直到有数据可读
是的,很傻很执着 :)
如果客户端再也不发送数据过来,那么就永远的等下去,这显然不够灵活
可以通过
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
设置等待时间
如果超过了这个等待时间,还没有收到数据就不等了,函数就返回
[b]非阻塞socket是这样的[/b]
调用函数
unsigned long ul = 1;
ioctlsocket(sServer, FIONBIO, (unsigned long*)&ul);
设置为非阻塞
然后调用
recv(socket1, buf, length);
这儿的执行方式为:去查看网卡缓冲区有无数据,如果有那么读取数据并返回,[color=red]如果没有不等待直接返回。[/color]这儿就是与阻塞socket的不同
非阻塞socket的数据读取方式:
BOOL SocketUtils::RecvNonBlock(SOCKET sock, char *buf, int length)
{
const static maxRecvTimes = 10;
int byteRead = 0; //已读字节数
for (int i = 0; i < maxRecvTimes; i++){
int nVal = recv(sock, buf + byteRead, length - byteRead, 0);
if(nVal > 0){ //读到数据
byteRead += nVal;
if(byteRead == length){
return TRUE;
}
}else if(nVal == SOCKET_ERROR){
if(WSAGetLastError() == WSAEWOULDBLOCK){ //非阻塞模式下,没数据可接收
printf("[%d]Sleep 50ms\n", i);
Sleep(50); //睡眠一会
}else{
printf("recv error. ErrorCode=%d\n", WSAGetLastError());
return FALSE;
}
}else if(nVal == 0){
printf("socket connection has closed!\n");
return FALSE;
}
}
printf("[Error] Socket Recv Over %d times\n", maxRecvTimes);
return FALSE;
}