linux select超时时间利用,LINUX下select设置超时

LINUX设置链接超时方法:服务器

非阻塞 connect:socket

在一个 TCP 套接字被设置为非阻塞以后调用 connect ,connect 会当即返回  EINPROGRESS  错误,表示链接操做正在进行中,可是仍未完成,与此同时 TCP 三次握手操做会同时进行。在这以后,咱们能够经过调用 select 来检查这个连接是否创建成功。函数

在阻塞套接字的通常状况下,connect ()直到客户端对SYN消息的ACK消息到达以前才会返回。使connect()调用具备超时机制的一个方法是让套接字成为非阻塞的套接字体,而后用select()来等待它完成。

s = socket(AF_INET, SOCK_STREAM, 0);

//下面获取套接字的标志

if ((flags = fcntl(s, F_GETFL, 0)) < 0) {

//错误处理

}字体

//下面设置套接字为非阻塞

if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {

//错误处理

}code

if ((retcode = connect(s, (struct sockaddr*)&peer, sizeof(peer)) &&

errno != EINPROGRESS) {

//由于套接字设为NONBLOCK,一般状况下,链接在connect()返回

//以前是不会创建的,所以它会返回EINPROGRESS错误,若是返回

//任何其余错误,则要进行错误处理

}接口

if (0 == retcode) {  //若是connect()返回0则链接已创建

//下面恢复套接字阻塞状态

if (fcntl(s, F_SETFL, flags) < 0) {

//错误处理

}get

//下面是链接成功后要执行的代码

exit(0)

}it

(要设备send/recv超时只需今后处开始修改相应值,前面不用)

FD_ZERO(&rdevents);

FD_SET(s, &rdevents);  //把先前的套接字加到读集合里面

wrevents = rdevents;   //写集合

exevents = rdevents;   //异常集合io

tv.tv_sec = 5;  //设置时间为5秒

tv_tv_usec = 0;event

retcode = select(s+1, &rdevents, &wrevents, &exevents, &tv);

if (retcode < 0) {  //select返回错误???

//错误处理

}

else if (0 == retcode) {  //select 超时???

//超时处理

}

esle {

//套接字已经准备好

if (!FD_ISSET(s, &rdevents) && !FD_ISSET(s, &wrevents)) {

//connect()失败,进行错处理

}

if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {

//getsockopt()失败,进行错处理

}

if (err != 0) {

//connect()失败,进行错处理

}

(send/recv超时到此为止,返回send()/recv()函数)

//到这里说明connect()正确返回

//下面恢复套接字阻塞状态

if (fcntl(s, F_SETFL, flags) < 0) {

//错误处理

}

//下面是链接成功后要执行的代码

exit(0)

处理非阻塞 connect 的步骤:

第一步,建立 socket,返回套接字描述符;

第二步,调用 fcntl 或 ioctlsocket 把套接口描述符设置成非阻塞;

第三步,调用 connect 开始创建链接;

第四步,判断链接是否成功创建:

A)若是 connect 返回 0 ,表示链接成功(服务器和客户端在同一台机器上时就有可能发生这种状况);

B)调用 select 来断定链接创建的是否成功;

若是 select 返回 0 ,则表示在 select 的超时时间内未能成功创建链接;咱们须要返回超时错误给用户,同时关闭链接,以防止TCP三次握手继续进行下去;

若是 select 返回大于 0 的值,则说明检测到可读或可写或异常的套接字描述符存在;此时咱们能够经过调用 getsockopt 来检测集合中的套接口上是否存在待处理的错误,若是链接创建是成功的,则经过 getsockopt(sockfd,SOL_SOCKET,SO_ERROR,(char *)&error,&len) 获取的 error 值将是 0 ,若是创建链接时遇到错误,则 error 的值是链接错误所对应的 errno 值,好比ECONNREFUSED,ETIMEDOUT等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值