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