UDP服务recvfrom函数设置非阻塞

2019-07-13 09:00发布

基本概念: 其实UDP的非阻塞也可以理解成和TCP是一样的,都是通过socket的属性去做。 方法一:通过fcntl函数将套接字设置为非阻塞模式 方法二:通过套接字选项SO_RECVTIMEO设置超时。 方法一源码,编译:g++ udp_server.cpp -o server
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11.  
  12. void Perror(const char *s)
  13. {
  14. perror(s);
  15. exit(EXIT_FAILURE);
  16. }
  17.  
  18. //设置非阻塞
  19. static void setnonblocking(int sockfd) {
  20. int flag = fcntl(sockfd, F_GETFL, 0);
  21. if (flag < 0) {
  22. Perror("fcntl F_GETFL fail");
  23. return;
  24. }
  25. if (fcntl(sockfd, F_SETFL, flag | O_NONBLOCK) < 0) {
  26. Perror("fcntl F_SETFL fail");
  27. }
  28. }
  29.  
  30. int main()
  31. {
  32. int sockfd;
  33. int port = 9527;
  34. struct sockaddr_in servaddr, cliaddr;
  35.  
  36. sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  37. if (sockfd == -1) {
  38. Perror("socket failed:");
  39. }
  40. setnonblocking(sockfd);
  41.  
  42. bzero(&servaddr, sizeof(servaddr));
  43. servaddr.sin_family = AF_INET;
  44. servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  45. servaddr.sin_port = htons(port);
  46.  
  47. if (bind(sockfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
  48. Perror("bind failed:");
  49. }
  50.  
  51. socklen_t len;
  52. for ( ; ; ) {
  53. char mesg[1024] = {};
  54. int n = recvfrom(sockfd, mesg, 1024, 0, (sockaddr *)&cliaddr, &len);
  55. sleep(1);
  56. perror("recvfrom fail: ");
  57. }
  58.  
  59. return 0;
  60. }
方法二源码,编译:g++ udp_server.cpp -o server
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11. #include
  12.  
  13. void Perror(const char *s)
  14. {
  15. perror(s);
  16. exit(EXIT_FAILURE);
  17. }
  18.  
  19. int main()
  20. {
  21. int sockfd;
  22. int port = 9527;
  23. struct sockaddr_in servaddr, cliaddr;
  24.  
  25. sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  26. if (sockfd == -1) {
  27. Perror("socket failed:");
  28. }
  29.  
  30. // 设置超时
  31. struct timeval timeout;
  32. timeout.tv_sec = 1;//秒
  33. timeout.tv_usec = 0;//微秒
  34. if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1) {
  35. Perror("setsockopt failed:");
  36. }
  37.  
  38. bzero(&servaddr, sizeof(servaddr));
  39. servaddr.sin_family = AF_INET;
  40. servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  41. servaddr.sin_port = htons(port);
  42.  
  43. if (bind(sockfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
  44. Perror("bind failed:");
  45. }
  46.  
  47. socklen_t len;
  48. for ( ; ; ) {
  49. char mesg[1024] = {};
  50. int n = recvfrom(sockfd, mesg, 1024, 0, (sockaddr *)&cliaddr, &len);
  51. perror("recvfrom fail: ");
  52.  
  53. }
  54.  
  55. return 0;
  56. }
  57.  
原文出自:http://blog.csdn.net/daiyudong2020/article/details/70039409