udpserver.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include <rtthread.h>
  2. #include <string.h>
  3. #if !defined(SAL_USING_POSIX)
  4. #error "Please enable SAL_USING_POSIX!"
  5. #else
  6. #include <sys/time.h>
  7. #include <sys/select.h>
  8. #endif
  9. #include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
  10. #include "netdb.h"
  11. #define DEBUG_UDP_SERVER
  12. #define DBG_ENABLE
  13. #define DBG_SECTION_NAME "UDP"
  14. #ifdef DEBUG_UDP_SERVER
  15. #define DBG_LEVEL DBG_LOG
  16. #else
  17. #define DBG_LEVEL DBG_INFO /* DBG_ERROR */
  18. #endif
  19. #define DBG_COLOR
  20. #include <rtdbg.h>
  21. #define BUFSZ 1024
  22. static int started = 0;
  23. static int is_running = 0;
  24. static int port = 5000;
  25. static void udpserv(void *paramemter)
  26. {
  27. int sock;
  28. int bytes_read;
  29. char *recv_data;
  30. socklen_t addr_len;
  31. struct sockaddr_in server_addr, client_addr;
  32. struct timeval timeout;
  33. fd_set readset;
  34. /* 分配接收用的数据缓冲 */
  35. recv_data = rt_malloc(BUFSZ);
  36. if (recv_data == RT_NULL)
  37. {
  38. LOG_E("No memory");
  39. return;
  40. }
  41. /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */
  42. if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  43. {
  44. LOG_E("Create socket error");
  45. goto __exit;
  46. }
  47. /* 初始化服务端地址 */
  48. server_addr.sin_family = AF_INET;
  49. server_addr.sin_port = htons(port);
  50. server_addr.sin_addr.s_addr = INADDR_ANY;
  51. rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
  52. /* 绑定socket到服务端地址 */
  53. if (bind(sock, (struct sockaddr *)&server_addr,
  54. sizeof(struct sockaddr)) == -1)
  55. {
  56. LOG_E("Unable to bind");
  57. goto __exit;
  58. }
  59. addr_len = sizeof(struct sockaddr);
  60. LOG_I("UDPServer Waiting for client on port %d...", port);
  61. started = 1;
  62. is_running = 1;
  63. timeout.tv_sec = 3;
  64. timeout.tv_usec = 0;
  65. while (is_running)
  66. {
  67. FD_ZERO(&readset);
  68. FD_SET(sock, &readset);
  69. /* Wait for read or write */
  70. if (select(sock + 1, &readset, RT_NULL, RT_NULL, &timeout) == 0)
  71. continue;
  72. /* 从sock中收取最大BUFSZ - 1字节数据 */
  73. bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0,
  74. (struct sockaddr *)&client_addr, &addr_len);
  75. if (bytes_read < 0)
  76. {
  77. LOG_E("Received error, close the connect.");
  78. goto __exit;
  79. }
  80. else if (bytes_read == 0)
  81. {
  82. LOG_W("Received warning, recv function return 0.");
  83. continue;
  84. }
  85. else
  86. {
  87. recv_data[bytes_read] = '\0'; /* 把末端清零 */
  88. /* 输出接收的数据 */
  89. LOG_D("Received data = %s", recv_data);
  90. /* 如果接收数据是exit,退出 */
  91. if (strcmp(recv_data, "exit") == 0)
  92. {
  93. goto __exit;
  94. }
  95. }
  96. }
  97. __exit:
  98. if (recv_data)
  99. {
  100. rt_free(recv_data);
  101. recv_data = RT_NULL;
  102. }
  103. if (sock >= 0)
  104. {
  105. closesocket(sock);
  106. sock = -1;
  107. }
  108. started = 0;
  109. is_running = 0;
  110. }
  111. static void usage(void)
  112. {
  113. rt_kprintf("Usage: udpserver -p <port>\n");
  114. rt_kprintf(" udpserver --stop\n");
  115. rt_kprintf(" udpserver --help\n");
  116. rt_kprintf("\n");
  117. rt_kprintf("Miscellaneous:\n");
  118. rt_kprintf(" -p Specify the host port number\n");
  119. rt_kprintf(" --stop Stop udpserver program\n");
  120. rt_kprintf(" --help Print help information\n");
  121. }
  122. static void udpserver_test(int argc, char** argv)
  123. {
  124. rt_thread_t tid;
  125. if (argc == 1 || argc > 3)
  126. {
  127. LOG_I("Please check the command you entered!\n");
  128. goto __usage;
  129. }
  130. else
  131. {
  132. if (rt_strcmp(argv[1], "--help") == 0)
  133. {
  134. goto __usage;
  135. }
  136. else if (rt_strcmp(argv[1], "--stop") == 0)
  137. {
  138. is_running = 0;
  139. return;
  140. }
  141. else if (rt_strcmp(argv[1], "-p") == 0)
  142. {
  143. if (started)
  144. {
  145. LOG_I("The tcpclient has started!");
  146. LOG_I("Please stop tcpclient firstly, by: tcpclient --stop");
  147. return;
  148. }
  149. port = atoi(argv[2]);
  150. }
  151. else
  152. {
  153. goto __usage;
  154. }
  155. }
  156. tid = rt_thread_create("udp_serv",
  157. udpserv, RT_NULL,
  158. 2048, RT_THREAD_PRIORITY_MAX/3, 20);
  159. if (tid != RT_NULL)
  160. {
  161. rt_thread_startup(tid);
  162. }
  163. return;
  164. __usage:
  165. usage();
  166. }
  167. #ifdef RT_USING_FINSH
  168. MSH_CMD_EXPORT_ALIAS(udpserver_test, udpserver,
  169. Start a udp server. Help: udpserver --help);
  170. #endif