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