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