轉自: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;