阻塞 非阻塞socket的理解

[b]阻塞socket是这样的[/b]
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值