fork download
  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <netdb.h>
  4. #include <unistd.h>
  5. #include <cstdio>
  6. #include <cerrno>
  7. #include <cstdlib>
  8. #include <poll.h>
  9. #include <vector>
  10. #include <arpa/inet.h>
  11.  
  12. int main (int ac, char **av) {
  13.  
  14. if(ac != 2) {
  15. fprintf(stderr, "Usage: %s portnumber\n", *av);
  16. return 1;
  17. }
  18.  
  19. struct addrinfo *res0;
  20. struct addrinfo hints = { 0, 0, SOCK_DGRAM };
  21. int rc = getaddrinfo(0, av[1], &hints, &res0);
  22. if(rc) {
  23. fprintf(stderr, "%s/%s: %s\n", av[1], av[2], gai_strerror(rc));
  24. return 1;
  25. }
  26.  
  27. char *name = res0->ai_canonname;
  28. std::vector<pollfd> fds;
  29. for(struct addrinfo *res = res0; res; res=res->ai_next) {
  30. fprintf(stderr, "%s: ", name);
  31. int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  32. if(fd < 0) {
  33. perror("socket");
  34. continue;
  35. }
  36.  
  37. rc = bind(fd, res->ai_addr, res->ai_addrlen);
  38. if(rc < 0) {
  39. perror("bind");
  40. continue;
  41. }
  42. fprintf(stderr, "Bound (%d)\n", fd);
  43. fds.push_back(pollfd({fd, POLLIN}));
  44. }
  45. freeaddrinfo(res0);
  46.  
  47. while( (rc = poll( &fds[0], fds.size(), -1)) > 0 ) {
  48. for(size_t i = 0; i < fds.size(); ++i) {
  49. pollfd& pfd = fds[i];
  50. if(!pfd.revents)
  51. continue;
  52. pfd.revents = 0;
  53.  
  54. union {
  55. sockaddr s;
  56. sockaddr_in sin;
  57. sockaddr_in6 sin6;
  58. } u;
  59. rc = recv(pfd.fd, &u, sizeof u, 0);
  60. if(rc < 0) {
  61. perror("recv");
  62. continue;
  63. }
  64. fprintf(stderr, "Received %d bytes\n", rc);
  65.  
  66. char str[256];
  67. switch(ntohs(u.s.sa_family)) {
  68. case AF_INET:
  69. if(inet_ntop(AF_INET, &u.sin.sin_addr, str, sizeof str)) {
  70. fprintf(stderr, "AF_INET %s\n", str);
  71. } else {
  72. fprintf(stderr, "AF_INET unknown\n");
  73. }
  74. break;
  75. case AF_INET6:
  76. if(inet_ntop(AF_INET6, &u.sin6.sin6_addr, str, sizeof str)) {
  77. fprintf(stderr, "AF_INET6 %s\n", str);
  78. } else {
  79. fprintf(stderr, "AF_INET6 unknown\n");
  80. }
  81. break;
  82. default:
  83. fprintf(stderr, "UNKNOWN\n");
  84. break;
  85. }
  86. }
  87. }
  88. }
  89.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty