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
udpserv(void * paramemter)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
usage(void)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
udpserver_test(int argc,char ** argv)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