本帖最后由 fs_te_ming 于 2013-03-14 14:04 编辑突然想想试试看,linux下的connect超时,两种方式实现 1)sigaction #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <sys/time.h> #include <unistd.h> #include <asm/ioctls.h> #include <signal.h> #define SERVPORT 13333 #define TIMEOUT_TIME 6 void connect_sigalarm() { printf("connect alarm.\n"); return; } int main(int argc,char *argv[]) { int sockfd; int retval; int error=-1; char *dest_ip; int ret=0; struct sockaddr_in serv_info; struct sigaction act,oldact; struct timeval tm; fd_set rset,wset; char buf[1024]; if(argc == 2) { dest_ip=argv[1]; } act.sa_handler = connect_sigalarm; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGALRM); act.sa_flags = SA_INTERRUPT; //由此信号中断的系统调用不会自动重启 sigaction(SIGALRM, &act, &oldact); if(alarm(5) != 0) { printf("alarm has already set.\n"); } memset(&serv_info,0,sizeof(serv_info)); serv_info.sin_family = AF_INET; serv_info.sin_port = htons(SERVPORT); serv_info.sin_addr.s_addr = inet_addr(dest_ip); sockfd = socket(PF_INET,SOCK_STREAM,0); if(sockfd<0) { perror("socket"); return 1; } if(connect(sockfd,(struct sockaddr *)&serv_info,sizeof(struct sockaddr))<0) { close(sockfd); if (errno == EINTR) { //errno=TIMEOUT; printf("connect timeout\n"); } } alarm(0); return 0; } 2)非阻塞的select #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <sys/time.h> #include <unistd.h> #include <asm/ioctls.h> #include <signal.h> #include <fcntl.h> #define SERVPORT 13333 #define TIMEOUT_TIME 6 int main(int argc,char *argv[]) { int sockfd; int retval; int error=-1; char *dest_ip; int len; int ret=0; struct sockaddr_in serv_info; struct sigaction act,oldact; struct timeval tm; fd_set rset,wset; char buf[1024]; if(argc == 2) { dest_ip=argv[1]; } memset(&serv_info,0,sizeof(serv_info)); serv_info.sin_family = AF_INET; serv_info.sin_port = htons(SERVPORT); serv_info.sin_addr.s_addr = inet_addr(dest_ip); sockfd = socket(PF_INET,SOCK_STREAM,0); if(sockfd<0) { perror("socket"); return 1; } if(fcntl(sockfd,F_SETFL,fcntl(sockfd,F_GETFL) | O_NONBLOCK)<0) { perror("fcntl"); close(sockfd); return 1; } if(connect(sockfd,(struct sockaddr *)&serv_info,sizeof(struct sockaddr))<0) { if(errno != EINPROGRESS) { perror("connect"); return 1; } tm.tv_sec = TIMEOUT_TIME; tm.tv_usec = 0; FD_ZERO(&wset); FD_SET(sockfd,&wset); retval = select(sockfd+1,NULL,&wset,NULL,&tm); switch(retval) { case -1: perror("select"); return 1; case 0: printf("timeout\n"); break; default: if(FD_ISSET(sockfd,&wset)) { if(getsockopt(sockfd,SOL_SOCKET,SO_ERROR,&error,(socklen_t *)&len)<0) { return 1; } printf("error=%d\n",error); if(error==0) { ret=1; } else { ret=0; errno=error; } } break; } } fcntl(sockfd,F_SETFL,fcntl(sockfd,F_GETFL) & O_NONBLOCK); //set back to block mode if(!ret) { close(sockfd); perror("connect failed"); return 1; } sprintf(buf,"%s","hello world!"); if(send(sockfd,buf,strlen(buf),0)<0) { perror("send"); } printf("connected\n"); return 0; } 均已测试通过,测试方式,服务端监听端口13333,设置iptables drop所有连接到这个端口的连接;客户端发起连接 |
linux socket connect超时设置
最新推荐文章于 2021-05-03 11:35:13 发布