#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <string.h> #include <signal.h> #include <unistd.h> static int sig_alrm(int); const int maxline=4096; int readable_timeo(int fd, int sec) { fd_set rset; struct timeval tv; FD_ZERO(&rset); FD_SET(fd, &rset); tv.tv_sec=sec; tv.tv_usec=0; return select(fd+1, &rset, NULL, NULL, &tv); } void dg_cli(FILE *fp, int sockfd, const struct sockaddr * pservaddr, socklen_t servlen) { int n; char sendline[maxline], recvline[maxline+1]; char errbuff[maxline]; while(fgets(sendline, maxline, fp) != NULL) { if(sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen)<0) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "sendto error: %s\n", errbuff); exit(-1); } if((n=recvfrom(sockfd, recvline, maxline, 0, NULL, NULL))<0) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "recvfrom error: %s\n", errbuff); exit(-1); } recvline[n]=0; fputs(recvline, stdout); } } void dg_cli_so(FILE *fp, int sockfd, const struct sockaddr * pservaddr, socklen_t servlen) { int n; char sendline[maxline], recvline[maxline+1]; char errbuff[maxline]; struct timeval tv; tv.tv_sec=5; tv.tv_usec=0; if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))==-1) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "setsockopt error: %s\n", errbuff); exit(-1); } while(fgets(sendline, maxline, fp) != NULL) { if(sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen)<0) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "sendto error: %s\n", errbuff); exit(-1); } n=recvfrom(sockfd, recvline, maxline, 0, NULL, NULL); if(n<0) { if(errno==EWOULDBLOCK) { fprintf(stderr, "socket timeout\n"); continue; } else { strerror_r(errno, errbuff, maxline); fprintf(stderr, "recvfrom error: %s\n", errbuff); exit(-1); } } recvline[n]=0; fputs(recvline, stdout); } } void dg_cli_select(FILE *fp, int sockfd, const struct sockaddr * pservaddr, socklen_t servlen) { int n; char sendline[maxline], recvline[maxline+1]; char errbuff[maxline]; while(fgets(sendline, maxline, fp) != NULL) { if(sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen)<0) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "sendto error: %s\n", errbuff); exit(-1); } if(readable_timeo(sockfd, 5)==0) { fprintf(stderr, "socket timeout\n"); } else { if((n=recvfrom(sockfd, recvline, maxline, 0, NULL, NULL))<0) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "recvfrom error: %s\n", errbuff); exit(-1); } recvline[n]=0; fputs(recvline, stdout); } } } void dg_cli_alrm(FILE *fp, int sockfd, const struct sockaddr * pservaddr, socklen_t servlen) { int n; char sendline[maxline], recvline[maxline+1]; char errbuff[maxline]; if(signal(SIGALRM, sig_alrm)<0) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "signal error: %s\n", errbuff); exit(-1); } while(fgets(sendline, maxline, fp) != NULL) { if(sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen)<0) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "sendto error: %s\n", errbuff); exit(-1); } alarm(5); if((n=recvfrom(sockfd, recvline, maxline, 0, NULL, NULL))<0) { if(errno==EINTR) { fprintf(stderr, "socket timeout\n"); } else { strerror_r(errno, errbuff, maxline); fprintf(stderr, "recvfrom error: %s\n", errbuff); exit(-1); } } else { alarm(0); recvline[n]=0; fputs(recvline, stdout); } } } int main(int argc, char **argv) { int sockfd, n; char recvline[maxline+1], errbuff[maxline]; struct sockaddr_in servaddr; if(argc != 2) { fprintf(stderr, "usage: a.out <IPaddress>\n"); exit(-1); } if((sockfd=socket(AF_INET, SOCK_DGRAM, 0))<0) { strerror_r(errno, errbuff, maxline); fprintf(stderr, "socket error: %s\n", errbuff); exit(-1); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(9999); if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr)<=0) { fprintf(stderr, "inet_pton error for %s", argv[1]); exit(-1); } dg_cli_so(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); return 0; } static int sig_alrm(int signo) { printf("signal alarm\n"); exit -1; }
标签:udp,超时,int,rset,tv,maxline,sendline,include,客户端 From: https://www.cnblogs.com/donggongdechen/p/16744582.html