套接字超时设置
来源:互联网 发布:康纳vs迪亚兹数据 编辑:程序博客网 时间:2024/05/21 10:11
来源:http://www.cnblogs.com/yuxingfirst/archive/2013/06/06/3120986.html
我们知道,对于一个套接字的读写(read/write)操作默认是阻塞的,如果当前套接字还不可读/写,那么这个操作会一直阻塞下去,这样对于一个需要高性能的服务器来说,是不能接受的。所以,我们可以在进行读写操作的时候可以指定超时值,这样就读写操作就不至于一直阻塞下去。
在涉及套接字的I/O操作上设置超时的方法有三种:
1:调用alarm,它在指定的超时期满时产生SIGALRM信号。这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用。
2:在select中阻塞等待I/O(select有内置的时间限制),依次代替直接阻塞在read或write调用上。(linux2.6以后的内核也可以使用epoll的epoll_wait)
3:使用较新的SO_RCVTIMEO和SO_SNDTIMEO套接字选项。这个方法的问题在于并非所有的实现都支持这两个套接字选项。
上述这三个技术都适用于输入和输出操作(read、write,及其变体recv/send, readv/writev, recvfrom,sendto)。不过我们也期待可以用于connect的技术,因为TCP内置的connect超时相当长(典型值为75秒),而我们在写服务器程序的时候,也不会希望一个连接的建立需要花费这么长时间。select可用来在connect上设置超时的先决条件是相应的套接字是非阻塞的,而那两个套接字选项对connect并不适用;同时也应当指出,前两个技术适用于任何描述符,而第三个技术仅仅适用于套接字描述符。
下边我们主要展示利用select进行connect超时设置的实例(比较常用):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include <time.h>
#define PORT 9900
#define MAXDATASIZE 5000
int
main(
int
argc,
char
**argv)
{
int
sockfd,nbytes;
char
buf[1024];
struct
hostent *he;
struct
sockaddr_in srvaddr;
if
(argc!=2)
{
perror
(
"Usage:client hostname\n"
);
return
0;
}
if
((he=gethostbyname(argv[1]))==NULL)
{
perror
(
"gethostbyname"
);
return
0;
}
if
((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror
(
"create socket error"
);
return
0;
}
bzero(&srvaddr,
sizeof
(srvaddr));
srvaddr.sin_family=AF_INET;
srvaddr.sin_port=htons(PORT);
srvaddr.sin_addr=*((
struct
in_addr *)he->h_addr);
fcntl(sockfd, F_SETFL, O_NONBLOCK);
timeval timeout = {3, 0};
if
(connect(sockfd,(
struct
sockaddr *)&srvaddr,
sizeof
(
struct
sockaddr)) == -1)
{
if
(
errno
!= EINPROGRESS ) {
close(sockfd);
perror
(
"connect error"
);
return
0;
}
}
fd_set readSet;
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
FD_SET(sockfd, &writeSet);
int
ret = select(sockfd + 1, &readSet, &writeSet, NULL, &timeout);
printf
(
"%d"
, ret);
}
在打开套接字然后调用connect的时候,由于我们对套接字设置了O_NONBLOCK选项,所以此时connect不会阻塞,通常是会返回-1,然后errno被设置为EINPROGRESS,表示连接仍在进行中,所以在后边,我们只要将这个套接字注册到select的
可写集合中(writeSet,因为这里是去连接对端服务器),然后在调用select的时候设置超时值,如本例中设置为3秒;那么在3秒后,如果连接仍未建立,那么select将返回0,表示超时;如果在3秒内连接成功建立,套接字变为可写状态,那么select将返回1。
注:关于另外两种方式,可以通过阅读:《unix网络编程》第一卷第14章。
- 套接字超时设置
- 套接字设置超时总结
- 阻塞套接字巧妙设置连接超时
- 给套接字设置超时检测
- 给套接字设置超时检测
- 阻塞TCP套接字connect超时设置
- UNIX网络编程——设置套接字超时
- Unix网络编程 高级IO套接字设置超时
- Socket编程实践(9) --套接字IO超时设置方法
- python字节序转换+设置套接字超时时间
- Socket编程实践(8) --套接字IO超时设置方法
- Socket编程实践(9) --套接字IO超时设置方法
- linux网络编程之套接字:套接字I/O超时设置方法和用select实现超时
- 套接字IO超时设置方法和用select实现超时
- 套接字超时接接收
- linux网络编程之socket(十一):套接字I/O超时设置方法和用select实现超时
- linux网络编程之socket(十一):套接字I/O超时设置方法和用select实现超时
- linux网络编程之socket(十一):套接字I/O超时设置方法和用select实现超时
- WebSphere上部署Web时 找不到用于处理 JSP 的扩展处理器
- Gnome排序
- gcc、g++、make的安装
- ip地址详解
- uva 465 - Overflow 大数加法 大数乘法
- 套接字超时设置
- 判断单链表是否有环
- 0802leetcode刷题总结
- CSS从大图片上截取小图标的操作
- hadoop fs -getmerge命令的使用
- SQLiteOpenHelper
- 未能够识别出目标 ***;票根
- 无需cygwin,使用NDK进行开发
- Jquery中的ajax