xref: /nrf52832-nimble/rt-thread/examples/network/udpserver.c (revision 104654410c56c573564690304ae786df310c91fc)
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