设置socket超时时间的两种方式
2016-12-31 17:01
597 查看
最近在编写fastcgi中,要通过udp请求后台其他服务数据。如果使用阻塞socket,万一由于网络等原因没有数据包返回,那么recvfrom将一直阻塞;如果使用非阻塞socket,后端服务还没有处理完请求返回数据前,recvfrom很可能已经返回了,从而接受不到响应数据包。所以这时就要设置超时时间,如果该socket超时之后仍然没有数据包到来,那么就直接返回。
2、稍微复杂的方式:利用select
设置socket超时时间的两种方式:
1、比较简洁的方式:利用setsockopt的SO_RCVTIMEO选项#include <iostream> #include <string> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <errno.h> int main() { int fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { printf("fait to create socket\n"); return -1; } struct timeval timeout_val; timeout_val.tv_sec = 5; // 超时时间 timeout_val.tv_usec = 0; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout_val, sizeof(timeout_val)) < 0) { printf("socket option SO_RCVTIMEO not support\n"); return -1; } struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(2222); char buf[1024] = "aaaaaaaaaa"; if (sendto(fd, buf, strlen(buf) , 0, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { printf("fail to sendto\n"); return -1; } sockaddr_in peer_addr; socklen_t addr_len = sizeof(peer_addr); int recv_len = 0; bzero(buf, sizeof(buf)); time_t start_time = time(NULL); recv_len = recvfrom(fd, buf, sizeof(buf), 0, reinterpret_cast<sockaddr*>(&peer_addr), &addr_len); printf("time_out=%d\n", time(NULL) - start_time); if (errno == EWOULDBLOCK || errno== EAGAIN) printf("recvfrom timeout\n"); else printf("recvfrom err:%d\n", recv_len); return 0; }
2、稍微复杂的方式:利用select
#include <iostream> #include <string> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <errno.h> int main() { int fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { printf("fait to create socket\n"); return -1; } struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(2222); char buf[1024] = "aaaaaaaaaa"; if (sendto(fd, buf, strlen(buf) , 0, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { printf("fail to sendto\n"); return -1; } sockaddr_in peer_addr; socklen_t addr_len = sizeof(peer_addr); int recv_len = 0; bzero(buf, sizeof(buf)); fd_set reasfds; FD_ZERO(&reasfds); FD_SET(fd, &reasfds); struct timeval timeout_val; timeout_val.tv_sec = 5; timeout_val.tv_usec = 0; int ret = select(fd+1, &reasfds, NULL, NULL, &timeout_val); if (ret > 0) { recv_len = recvfrom(fd, buf, sizeof(buf), 0, reinterpret_cast<sockaddr*>(&peer_addr), &addr_len); if (recv_len < 0) printf("recvfrom err, errno=%d\n", errno); } else if (ret == 0) { printf("recvfrom timeout\n"); } else { printf("select err, errno=%d\n", errno); } return 0; }
相关文章推荐
- socket的send、recv阻塞设置阻塞超时时间
- python subprocess模块 监控子进程的2种方式 忙等待和立即返回同时设置子进程超时时间 - 转
- 设置session超时时间的两种方法
- session缓存时间的两种设置方式
- socket为send和recv设置超时时间
- VC socket Connect 超时时间设置
- python subprocess模块 监控子进程的2种方式 忙等待和立即返回同时设置子进程超时时间
- socket的send、recv阻塞设置阻塞超时时间
- socket为send和recv设置超时时间
- C++ 之Socket 编程 send rev 阻塞设置 阻塞超时时间
- CXF 客户端超时时间设置(非Spring配置方式)
- socket连接超时的问题,设置限定时间
- [转]socket的send、recv阻塞设置阻塞超时时间
- 基于XSocket框架的socket编程技巧(设置连接的超时时间和最大空闲时间)
- Socket 关于设置Socket连接超时时间
- socket的send、recv阻塞设置阻塞超时时间
- socket的send、recv阻塞设置阻塞超时时间
- Socket 关于设置Socket连接超时时间
- socket为send和recv设置 4000 超时时间
- socket中各个阻塞,非阻塞,初始化和超时时间设置