我正在尝试实现一个recv超时为1秒的套接字:
int sockfd;
struct sockaddr_in self;
struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);
ssize_t nBytes;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
self.sin_family = AF_INET;
self.sin_port = htons(PORT);
self.sin_addr.s_addr = INADDR_ANY;
int on = 1;
setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on);
// 1 Sec Timeout
tv.tv_sec = 1;
tv.tv_usec = 0;
setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv);
bind(sockfd, (struct sockaddr*)&self, sizeof(self));
listen(sockfd, 20);
clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);
nBytes = recv(clientfd, buffer, MAXBUF-1, 0);
Run Code Online (Sandbox Code Playgroud)
没有'setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv);'调用接受和recv工作,但recv阻止.
使用'setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv);'接受调用会产生错误'资源暂时不可用'.
有人可以告诉我这种方法有什么问题吗?
你希望哪个套接字有一秒超时?接受连接的那个,还是accept()建立的连接?
我假设后者 - 所以尝试在accept返回后在clientfd上设置接收超时.您也可以到达需要使用select的位置,但您不需要.
这有点偏离主题,但我真的想分享这个解决方案来在windows和unix上设置recv超时.也许是我,但我花了很多时间弄清楚为什么我的程序不起作用以及如何正确设置超时.希望你觉得它有用.它将超时设置为10秒.
对于Windows:
DWORD sock_timeout = 10*1000;
Run Code Online (Sandbox Code Playgroud)
对于Unix:
const struct timeval sock_timeout={.tv_sec=10, .tv_usec=0};
Run Code Online (Sandbox Code Playgroud)
对彼此而言:
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&sock_timeout, sizeof(sock_timeout));
Run Code Online (Sandbox Code Playgroud)
在调用recv() 或accept() 之前尝试使用select()。
select() 接受一组文件描述符(包括套接字),并在其中至少一个准备好接收时返回。它还可以在超时时返回。
在linux中你也可以尝试poll()(不确定Winsock是否提供这个)。
| 归档时间: |
|
| 查看次数: |
38482 次 |
| 最近记录: |