【转】UDP服务recvfrom函数设置非阻塞
转自:https://blog.csdn.net/daiyudong2020/article/details/70039409
基本概念:
其实UDP的非阻塞也可以理解成和TCP是一样的,都是通过socket的属性去做。
方法一:通过fcntl函数将套接字设置为非阻塞模式。
方法二:通过套接字选项SO_RECVTIMEO设置超时。
方法一源码,编译:g++ udp_server.cpp -o server
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <errno.h> #include <strings.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fcntl.h> #include <unistd.h> void Perror(const char *s) { perror(s); exit(EXIT_FAILURE); } //设置非阻塞 static void setnonblocking(int sockfd) { int flag = fcntl(sockfd, F_GETFL, 0); if (flag < 0) { Perror("fcntl F_GETFL fail"); return; } if (fcntl(sockfd, F_SETFL, flag | O_NONBLOCK) < 0) { Perror("fcntl F_SETFL fail"); } } int main() { int sockfd; int port = 9527; struct sockaddr_in servaddr, cliaddr; sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { Perror("socket failed:"); } setnonblocking(sockfd); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servaddr.sin_port = htons(port); if (bind(sockfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1) { Perror("bind failed:"); } socklen_t len; for ( ; ; ) { char mesg[1024] = {}; int n = recvfrom(sockfd, mesg, 1024, 0, (sockaddr *)&cliaddr, &len); sleep(1); perror("recvfrom fail: "); } return 0; }
方法二源码,编译:g++ udp_server.cpp -o server
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <errno.h> #include <strings.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fcntl.h> #include <unistd.h> #include <sys/time.h> void Perror(const char *s) { perror(s); exit(EXIT_FAILURE); } int main() { int sockfd; int port = 9527; struct sockaddr_in servaddr, cliaddr; sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { Perror("socket failed:"); } // 设置超时 struct timeval timeout; timeout.tv_sec = 1;//秒 timeout.tv_usec = 0;//微秒 if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1) { Perror("setsockopt failed:"); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servaddr.sin_port = htons(port); if (bind(sockfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1) { Perror("bind failed:"); } socklen_t len; for ( ; ; ) { char mesg[1024] = {}; int n = recvfrom(sockfd, mesg, 1024, 0, (sockaddr *)&cliaddr, &len); perror("recvfrom fail: "); } return 0; }
原文出自:http://blog.csdn.net/daiyudong2020/article/details/70039409
End;