套接字中connect阻塞与非阻塞问题

原文地址:http://bbs.csdn.net/topics/340155739

1
int  PASCAL FAR connect (SOCKET s,  const  struct  sockaddr FAR *name,  int  namelen);

(1)如果服务器端程序已经运行, 客户端执行connect()函数,正常没问题,
(2)如果服务端程序没有运行的时候,客户端执行connect()函数,会在此函数停留很长时间,整个程序界面几乎死掉,要3秒左右才能执行完connect()函数并返回结果,

请问如何在(2)的情况下让connect函数立刻返回?


//设置非阻塞方式连接
unsigned long ul = 1;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)return 0;

//连接
server.sin_family = AF_INET;
server.sin_port = htons(25);
server.sin_addr .s_addr = inet_addr((LPCSTR)pSmtp);
if(server.sin_addr.s_addr == INADDR_NONE){return 0;}

connect(cClient,(const struct sockaddr *)&server,sizeof(server));

//select 模型,即设置超时
struct timeval timeout ;
fd_set r;

FD_ZERO(&r);
FD_SET(cClient, &r);
timeout.tv_sec = 15; //连接超时15秒
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(cClient);
return 0;
}
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR){
::closesocket (cClient);
return 0;

在C语言,设置套接字非阻塞(也称为异步)状态,意味着当试图执行某些I/O操作(如读写)但没有立即完成时,而不是让程序陷入阻塞等待,操作系统将返回一个错误标识,这样程序可以继续执行其他任务。这对于高并发服务器至关重要,因为它们需要能够快速响应多个请求而不被单个请求阻碍。 设置套接字非阻塞的基本步骤如下: 1. **打开套接字**:首先,你需要创建一个新的套接字(`socket()`),或者已经存在的套接字(比如通过`accept()`获取的新连接)。 2. **检查是否已设置阻塞**:对于已经存在的套接字,你可以通过`fcntl()`函数和`F_GETFL`标志来检查其当前的阻塞属性,如果它是阻塞的,你需要将其改为非阻塞。 ```c int flags; fcntl(socket_fd, F_GETFL, &flags); flags &= ~O_NONBLOCK; // 如果之前是阻塞的,移除O_NONBLOCK标志 fcntl(socket_fd, F_SETFL, flags); ``` 3. **处理错误**:在改变套接字阻塞属性时,可能会出现`EAGAIN`或`EWOULDBLOCK`错误,这是正常的,表示操作需要立即完成,所以你应该捕获这些错误并重新尝试操作。 如果你使用的是`connect()`,则可能在连接未建立完成时遇到此问题,此时应该直接抛出异常或者定期重试。 4. **检测I/O完成**:在后续的I/O操作,当没有数据可读或写入完成时,`read()`和`write()`函数会返回`-1`,并且错误码可能是`EAGAIN`或`EWOULDBLOCK`。这时你可以选择睡眠一段时间后再试,或者使用`epoll`、`select`等工具轮询,等待I/O事件发生。 请注意,在生产环境,设置为非阻塞并不是万能的,还需要配合合适的时间管理策略,如超时、重试机制等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值