server.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include <st.h>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <arpa/inet.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <getopt.h>
  10. struct message {
  11. st_netfd_t stfd;
  12. sockaddr_in peer;
  13. int delay;
  14. };
  15. void* sender(void* arg)
  16. {
  17. message* p = (message*)arg;
  18. int delay = p->delay;
  19. if (delay > 0) {
  20. st_usleep(delay * 1000);
  21. }
  22. msghdr msg;
  23. memset(&msg, 0, sizeof(msghdr));
  24. sockaddr_in peer = p->peer;
  25. msg.msg_name = (sockaddr_in*)&peer;
  26. msg.msg_namelen = sizeof(sockaddr_in);
  27. char buf[] = "World";
  28. iovec iov;
  29. memset(&iov, 0, sizeof(iovec));
  30. iov.iov_base = buf;
  31. iov.iov_len = sizeof(buf);
  32. msg.msg_iov = &iov;
  33. msg.msg_iovlen = 1;
  34. st_netfd_t stfd = p->stfd;
  35. int r0 = st_sendmsg(stfd, &msg, 0, ST_UTIME_NO_TIMEOUT);
  36. assert(r0 > 0);
  37. printf("Pong %s:%d %d bytes, flags %#x, %s\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port), r0,
  38. msg.msg_flags, msg.msg_iov->iov_base);
  39. return NULL;
  40. }
  41. void usage(int argc, char** argv)
  42. {
  43. printf("Usage: %s <options>\n", argv[0]);
  44. printf("Options:\n");
  45. printf(" --help Print this help and exit.\n");
  46. printf(" --host=string The host to send to.\n");
  47. printf(" --port=int The port to send to.\n");
  48. printf(" --pong=bool Whether response pong, true|false\n");
  49. printf(" --delay=int The delay in ms to response pong.\n");
  50. printf("For example:\n");
  51. printf(" %s --host=0.0.0.0 --port=8000 --pong --delay=100\n", argv[0]);
  52. }
  53. int main(int argc, char** argv)
  54. {
  55. option longopts[] = {
  56. { "host", required_argument, NULL, 'o' },
  57. { "port", required_argument, NULL, 'p' },
  58. { "pong", required_argument, NULL, 'n' },
  59. { "delay", required_argument, NULL, 'd' },
  60. { "help", no_argument, NULL, 'h' },
  61. { NULL, 0, NULL, 0 }
  62. };
  63. char* host = NULL; char ch;
  64. int port = 0; int delay = 0; bool pong = false;
  65. while ((ch = getopt_long(argc, argv, "o:p:n:d:h", longopts, NULL)) != -1) {
  66. switch (ch) {
  67. case 'o': host = (char*)optarg; break;
  68. case 'p': port = atoi(optarg); break;
  69. case 'n': pong = !strcmp(optarg,"true"); break;
  70. case 'd': delay = atoi(optarg); break;
  71. case 'h': usage(argc, argv); exit(0);
  72. default: usage(argc, argv); exit(-1);
  73. }
  74. }
  75. printf("Server listen %s:%d, pong %d, delay: %dms\n", host, port, pong, delay);
  76. if (!host || !port) {
  77. usage(argc, argv);
  78. exit(-1);
  79. }
  80. assert(!st_set_eventsys(ST_EVENTSYS_ALT));
  81. assert(!st_init());
  82. int fd = socket(PF_INET, SOCK_DGRAM, 0);
  83. assert(fd > 0);
  84. int n = 1;
  85. int r0 = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof(n));
  86. assert(!r0);
  87. sockaddr_in addr;
  88. memset(&addr, 0, sizeof(sockaddr_in));
  89. addr.sin_family = AF_INET;
  90. addr.sin_port = htons(port);
  91. addr.sin_addr.s_addr = inet_addr(host);
  92. r0 = bind(fd, (sockaddr *)&addr, sizeof(sockaddr_in));
  93. assert(!r0);
  94. st_netfd_t stfd = st_netfd_open_socket(fd);
  95. assert(stfd);
  96. printf("Listen at udp://%s:%d, fd=%d\n", host, port, fd);
  97. msghdr msg;
  98. memset(&msg, 0, sizeof(msghdr));
  99. sockaddr_in peer;
  100. memset(&peer, 0, sizeof(sockaddr_in));
  101. msg.msg_name = (sockaddr_in*)&peer;
  102. msg.msg_namelen = sizeof(sockaddr_in);
  103. char buf[1500];
  104. memset(buf, 0, sizeof(buf));
  105. iovec iov;
  106. memset(&iov, 0, sizeof(iovec));
  107. iov.iov_base = buf;
  108. iov.iov_len = sizeof(buf);
  109. msg.msg_iov = &iov;
  110. msg.msg_iovlen = 1;
  111. int nn_msgs = 0;
  112. while (true) {
  113. r0 = st_recvmsg(stfd, &msg, 0, ST_UTIME_NO_TIMEOUT);
  114. assert(r0 > 0);
  115. printf("#%d, From %s:%d %d bytes, flags %#x, %s\n", nn_msgs++, inet_ntoa(peer.sin_addr), ntohs(peer.sin_port),
  116. r0, msg.msg_flags, msg.msg_iov->iov_base);
  117. if (pong) {
  118. message* msg = new message();
  119. msg->stfd = stfd;
  120. msg->peer = peer;
  121. msg->delay = delay;
  122. st_thread_t r0 = st_thread_create(sender, msg, 0, 0);
  123. assert(r0);
  124. }
  125. }
  126. return 0;
  127. }