Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6541522
  • 博文数量: 1159
  • 博客积分: 12444
  • 博客等级: 上将
  • 技术积分: 12570
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-13 21:34
文章分类

全部博文(1159)

文章存档

2016年(126)

2015年(350)

2014年(56)

2013年(91)

2012年(182)

2011年(193)

2010年(138)

2009年(23)

分类: C/C++

2016-01-18 15:52:33

http://neokentblog.blogspot.com/2012/11/udp-broadcast-socket-programming-example.html

server.c

点击(此处)折叠或打开

  1. // gcc server.c -o server
  2. // indent -npro -kr -i8 -ts8 -sob -l280 -ss -ncs -cp1 *

  3. #include <stdio.h>        // for printf() and fprintf()
  4. #include <sys/socket.h>        // for socket(), bind(), and connect()
  5. #include <arpa/inet.h>        // for sockaddr_in and inet_ntoa()
  6. #include <stdlib.h>        // for atoi() and exit()
  7. #include <string.h>        // for memset()
  8. #include <unistd.h>        // for close()
  9. #include <fcntl.h>        // for fcntl()
  10. #include <errno.h>

  11. #include <sys/epoll.h>

  12. #define BUFSIZE 1024        // Size of receive buffer

  13. static int make_socket_non_blocking(int sfd)
  14. {
  15.     int flags, s;

  16.     flags = fcntl(sfd, F_GETFL, 0);

  17.     if (flags == -1) {
  18.         perror("fcntl");
  19.         return -1;
  20.     }

  21.     flags |= O_NONBLOCK;
  22.     s = fcntl(sfd, F_SETFL, flags);

  23.     if (s == -1) {
  24.         perror("fcntl");
  25.         return -1;
  26.     }

  27.     return 0;
  28. }

  29. int main(int argc, char *argv[])
  30. {
  31.     int sockfd;        // Socket descriptors for server
  32.     int broadcast = 1;    // Socket Option.
  33.     struct sockaddr_in srvaddr;    // Broadcast Server Address
  34.     struct sockaddr_in dstaddr;    // Broadcast Destination Address
  35.     struct sockaddr_in cliaddr;    // Broadcast Response Client Address
  36.     int cliaddr_len = sizeof(cliaddr);

  37.     char buffer[BUFSIZE];    // Input and Receive buffer
  38.     int i;            // For loop use
  39.     int running = 1;    // Main Loop

  40.     int epfd;        // EPOLL File Descriptor.
  41.     struct epoll_event ev;    // Used for EPOLL.
  42.     struct epoll_event events[5];    // Used for EPOLL.
  43.     int noEvents;        // EPOLL event number.

  44.     printf("This process is a UDP broadcast process!.\n");

  45.     // Test for correct number of arguments

  46.     if (argc < 4) {
  47.         fprintf(stderr, "Usage: %s ...\n", argv[0]);
  48.         exit(1);
  49.     }
  50.     // Create Socket

  51.     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  52.         perror("Create Sockfd Fail!!\n");
  53.         exit(1);
  54.     }
  55.     // Setup Broadcast Option

  56.     if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast))) == -1) {
  57.         perror("Setsockopt - SO_SOCKET Fail!!\n");
  58.         exit(1);
  59.     }
  60.     // Nonblocking

  61.     make_socket_non_blocking(sockfd);

  62.     // Reset the addresses

  63.     memset(&srvaddr, 0, sizeof(srvaddr));
  64.     memset(&dstaddr, 0, sizeof(dstaddr));

  65.     // Setup the addresses

  66.     srvaddr.sin_family = AF_INET;
  67.     srvaddr.sin_port = htons(atoi(argv[1]));
  68.     srvaddr.sin_addr.s_addr = INADDR_ANY;

  69.     if (bind(sockfd, (struct sockaddr *)&srvaddr, sizeof(srvaddr)) == -1) {
  70.         perror("bind");
  71.         exit(1);
  72.     }

  73.     dstaddr.sin_family = AF_INET;
  74.     dstaddr.sin_port = htons(atoi(argv[3]));
  75.     inet_pton(AF_INET, argv[2], &(dstaddr.sin_addr.s_addr));

  76.     // Create epoll file descriptor.

  77.     epfd = epoll_create(5);

  78.     // Add socket into the EPOLL set.

  79.     ev.data.fd = sockfd;
  80.     ev.events = EPOLLIN | EPOLLET;
  81.     epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);

  82.     // Add STDIN into the EPOLL set.

  83.     ev.data.fd = STDIN_FILENO;
  84.     ev.events = EPOLLIN | EPOLLET;
  85.     epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);

  86.     while (running) {
  87.         // Wait for events.
  88.         // int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
  89.         // Specifying a timeout of -1 makes epoll_wait() wait indefinitely.

  90.         noEvents = epoll_wait(epfd, events, FD_SETSIZE, -1);

  91.         for (i = 0; i < noEvents; i++) {
  92.             if (events[i].events & EPOLLIN && STDIN_FILENO == events[i].data.fd) {
  93.                 memset(buffer, 0, BUFSIZE);
  94.                 fgets(buffer, 1024, stdin);

  95.                 if (strncmp(buffer, "bye", 3) == 0) {
  96.                     printf("Bye.\n");
  97.                     running = 0;
  98.                 }

  99.                 if (sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&dstaddr, sizeof(dstaddr)) != -1) {
  100.                     printf("Sent a brocast message: %s", buffer);
  101.                 } else {
  102.                     printf("Sent a brocast message FAIL!!\n");
  103.                     running = 0;
  104.                 }
  105.             } else if (events[i].events & EPOLLIN && sockfd == events[i].data.fd) {
  106.                 memset(buffer, 0, BUFSIZE);

  107.                 while (recvfrom(sockfd, buffer, BUFSIZE, 0, (struct sockaddr *)&cliaddr, (socklen_t *) & cliaddr_len) != -1) {
  108.                     printf("Response from %s_%d: %s", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), buffer);
  109.                 }

  110.                 if (errno != EAGAIN) {
  111.                     printf("Receive the brocast message response FAIL!!\n");
  112.                     running = 0;
  113.                 }
  114.             }
  115.         }
  116.     }

  117.     // Close the socket

  118.     close(sockfd);
  119.     close(epfd);

  120.     return 0;
  121. }
client.c

点击(此处)折叠或打开

  1. // gcc client.c -o client
  2. // indent -npro -kr -i8 -ts8 -sob -l280 -ss -ncs -cp1 *

  3. #include <stdio.h>        // for printf() and fprintf()
  4. #include <sys/socket.h>        // for socket(), bind(), and connect()
  5. #include <arpa/inet.h>        // for sockaddr_in and inet_ntoa()
  6. #include <stdlib.h>        // for atoi() and exit()
  7. #include <string.h>        // for memset()
  8. #include <unistd.h>        // for close()
  9. #include <fcntl.h>        // for fcntl()
  10. #include <errno.h>

  11. #include <sys/epoll.h>

  12. #define BUFSIZE 1024        // Size of receive buffer

  13. static int make_socket_non_blocking(int sfd)
  14. {
  15.     int flags, s;

  16.     flags = fcntl(sfd, F_GETFL, 0);

  17.     if (flags == -1) {
  18.         perror("fcntl");
  19.         return -1;
  20.     }

  21.     flags |= O_NONBLOCK;
  22.     s = fcntl(sfd, F_SETFL, flags);

  23.     if (s == -1) {
  24.         perror("fcntl");
  25.         return -1;
  26.     }

  27.     return 0;
  28. }

  29. int main(int argc, char *argv[])
  30. {
  31.     int sockfd;        // Socket descriptors for server
  32.     int broadcast = 1;    // Socket Option.
  33.     struct sockaddr_in cliaddr;    // Broadcast Receiver Address
  34.     struct sockaddr_in srvaddr;    // Broadcast Server Address
  35.     int srvaddr_len = sizeof(srvaddr);

  36.     char buffer[BUFSIZE];    // Input and Receive buffer
  37.     int i;            // For loop use
  38.     int running = 1;    // Main Loop
  39.     int rcvlen = 0;        // Receive Message Size

  40.     int epfd;        // EPOLL File Descriptor.
  41.     struct epoll_event ev;    // Used for EPOLL.
  42.     struct epoll_event events[5];    // Used for EPOLL.
  43.     int noEvents;        // EPOLL event number.

  44.     printf("This process is a UDP broadcast echo client process!.\n");

  45.     // Test for correct number of arguments

  46.     if (argc < 2) {
  47.         fprintf(stderr, "Usage: %s ...\n", argv[0]);
  48.         exit(1);
  49.     }
  50.     // Create Socket

  51.     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  52.         perror("Create Sockfd Fail!!\n");
  53.         exit(1);
  54.     }
  55.     // Nonblocking

  56.     make_socket_non_blocking(sockfd);

  57.     // Reset the addresses

  58.     memset(&cliaddr, 0, sizeof(cliaddr));

  59.     // Setup the addresses

  60.     cliaddr.sin_family = AF_INET;
  61.     cliaddr.sin_port = htons(atoi(argv[1]));
  62.     cliaddr.sin_addr.s_addr = INADDR_ANY;

  63.     if (bind(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)) == -1) {
  64.         perror("bind");
  65.         exit(1);
  66.     }
  67.     // Create epoll file descriptor.

  68.     epfd = epoll_create(5);

  69.     // Add socket into the EPOLL set.

  70.     ev.data.fd = sockfd;
  71.     ev.events = EPOLLIN | EPOLLET;
  72.     epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);

  73.     while (running) {
  74.         // Wait for events.
  75.         // int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
  76.         // Specifying a timeout of -1 makes epoll_wait() wait indefinitely.

  77.         noEvents = epoll_wait(epfd, events, FD_SETSIZE, -1);

  78.         for (i = 0; i < noEvents; i++) {
  79.             if (events[i].events & EPOLLIN && sockfd == events[i].data.fd) {
  80.                 memset(buffer, 0, BUFSIZE);

  81.                 while ((rcvlen = recvfrom(sockfd, buffer, BUFSIZE, 0, (struct sockaddr *)&srvaddr, (socklen_t *) & srvaddr_len))
  82.                  != -1) {
  83.                     printf("Receive from %s_%d: %s", inet_ntoa(srvaddr.sin_addr), ntohs(srvaddr.sin_port), buffer);

  84.                     if (sendto(sockfd, buffer, rcvlen, 0, (struct sockaddr *)&srvaddr, sizeof(srvaddr)) == -1) {
  85.                         printf("Send Fail!\n");
  86.                         running = 0;
  87.                         continue;
  88.                     }
  89.                 }

  90.                 if (errno != EAGAIN) {
  91.                     perror("Receive the brocast message response FAIL!!\n");
  92.                     running = 0;
  93.                 }
  94.             }
  95.         }
  96.     }

  97.     // Close the socket

  98.     close(sockfd);
  99.     close(epfd);

  100.     return 0;
  101. }



阅读(1383) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~