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