您的位置:首页 > 理论基础 > 计算机网络

TCP/IP协议:connect系统超时连接控制(2)

2016-04-03 08:39 615 查看
SO_SNDTIMEO方法

SO_RCVTIMEO和SO_SNDTIMEO套接口选项可以给套接口的读和写,来设置超时时间,在unix网络编程中,说是他们只能用于读和写,而像 accept和connect都不能用他们来设置.可是我在阅读内核源码的过程中看到,在linux中,accept和connect可以分别用 SO_RCVTIMEO和SO_SNDTIMEO套接口来设置超时,这里他们的超时时间也就是sock的sk_rcvtimeo和sk_sndtimeo 域.accept和connect的相关代码我前面都介绍过了,这里再提一下.其中accept的相关部分在inet_csk_accept中,会调用
sock_rcvtimeo来取得超时时间(如果是非阻塞则忽略超时间).而connect的相关代码在inet_stream_connect中通过调用sock_sndtimeo来取得超时时间(如果非阻塞则忽略超时时间).

File: net/ipv4/af_inet.c

timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);

if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {

/* Error code is set above */

if (!timeo || !inet_wait_for_connect(sk, timeo))

goto out;

err = sock_intr_errno(timeo);

if (signal_pending(current))

goto out;

}

测试代码

#include <stdlib.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <errno.h>

int main(int argc, char *argv[])

{

int fd;

struct sockaddr_in addr;

struct timeval timeo = {3, 0};

socklen_t len = sizeof(timeo);

fd = socket(AF_INET, SOCK_STREAM, 0);

if (argc == 4)

timeo.tv_sec = atoi(argv[3]);

setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len);

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = inet_addr(argv[1]);

addr.sin_port = htons(atoi(argv[2]));

if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {

if (errno == EINPROGRESS) {

fprintf(stderr, "timeout/n");

return -1;

}

perror("connect");

return 0;

}

printf("connected/n");

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: