1 /*
2 * Net Test Utilities for RT-Thread
3 */
4 #include <rtthread.h>
5 #include <finsh.h>
6 #include <lwip/api.h>
7 #include <lwip/sockets.h>
8 #include <lwip/init.h>
9
10 /*
11 * UDP echo server
12 */
13 #define UDP_ECHO_PORT 7
14 rt_thread_t udpecho_tid = RT_NULL;
udpecho_entry(void * parameter)15 void udpecho_entry(void *parameter)
16 {
17 struct netconn *conn;
18 struct netbuf *buf;
19 struct ip_addr *addr;
20 unsigned short port;
21
22 conn = netconn_new(NETCONN_UDP);
23 netconn_bind(conn, IP_ADDR_ANY, 7);
24
25 while(1)
26 {
27 /* received data to buffer */
28 #if LWIP_VERSION_MINOR==3U
29 buf = netconn_recv(conn);
30 #else
31 netconn_recv(conn, &buf);
32 #endif
33
34 addr = netbuf_fromaddr(buf);
35 port = netbuf_fromport(buf);
36
37 /* send the data to buffer */
38 netconn_connect(conn, addr, port);
39
40 /* reset address, and send to client */
41 #if LWIP_VERSION_MINOR==3U
42 buf->addr = RT_NULL;
43 #else
44 buf->addr = *IP_ADDR_ANY;
45 #endif
46
47 netconn_send(conn, buf);
48
49 /* release buffer */
50 netbuf_delete(buf);
51 }
52 }
53 /*
54 * UDP socket echo server
55 */
56 #define UDP_SOCKET_ECHO_PORT 700
57 #define UDP_SOCKET_BUFFER_SIZE 4096
58 rt_thread_t udpecho_socket_tid = RT_NULL;
udpecho_socket_entry(void * parameter)59 void udpecho_socket_entry(void *parameter)
60 {
61 int sock;
62 int bytes_read;
63 char *recv_data;
64 rt_uint32_t addr_len;
65 struct sockaddr_in server_addr, client_addr;
66
67 /* allocate the data buffer */
68 recv_data = rt_malloc(UDP_SOCKET_BUFFER_SIZE);
69 if (recv_data == RT_NULL)
70 {
71 /* no memory yet */
72 rt_kprintf("no memory\n");
73 goto _exit;
74 }
75 /* create a UDP socket */
76 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
77 {
78 rt_kprintf("create socket error\n");
79 goto _exit;
80 }
81
82 /* initialize server address */
83 server_addr.sin_family = AF_INET;
84 server_addr.sin_port = htons(UDP_SOCKET_ECHO_PORT);
85 server_addr.sin_addr.s_addr = INADDR_ANY;
86 rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));
87
88 /* bind socket to server address */
89 if (bind(sock,(struct sockaddr *)&server_addr,
90 sizeof(struct sockaddr)) == -1)
91 {
92 /* bind failed */
93 rt_kprintf("bind error\n");
94 goto _exit;
95 }
96
97 addr_len = sizeof(struct sockaddr);
98 while (1)
99 {
100 /* try to receive from UDP socket */
101 bytes_read = recvfrom(sock, recv_data, UDP_SOCKET_BUFFER_SIZE, 0,
102 (struct sockaddr *)&client_addr, &addr_len);
103
104 /* send back */
105 sendto(sock, recv_data, bytes_read, 0,
106 (struct sockaddr *)&client_addr, addr_len);
107 }
108
109 _exit:
110 rt_free(recv_data);
111 return;
112 }
113
114 /*
115 * TCP echo server
116 */
117 #define TCP_ECHO_PORT 7
118 rt_thread_t tcpecho_tid = RT_NULL;
tcpecho_entry(void * parameter)119 void tcpecho_entry(void *parameter)
120 {
121 struct netconn *conn, *newconn;
122 err_t err;
123
124 /* Create a new connection identifier. */
125 conn = netconn_new(NETCONN_TCP);
126
127 /* Bind connection to well known port number 7. */
128 netconn_bind(conn, NULL, TCP_ECHO_PORT);
129
130 /* Tell connection to go into listening mode. */
131 netconn_listen(conn);
132
133 while(1)
134 {
135 /* Grab new connection. */
136 #if LWIP_VERSION_MINOR==3U
137 newconn = netconn_accept(conn);
138 if(newconn != NULL)
139 #else
140 err = netconn_accept(conn, &newconn);
141 if(err == ERR_OK)
142 #endif
143 /* Process the new connection. */
144 {
145 struct netbuf *buf;
146 void *data;
147 u16_t len;
148 #if LWIP_VERSION_MINOR==3U
149 while((buf = netconn_recv(newconn)) != NULL)
150 #else
151 while((err = netconn_recv(newconn, &buf)) == ERR_OK)
152 #endif
153 {
154 do
155 {
156 netbuf_data(buf, &data, &len);
157 err = netconn_write(newconn, data, len, NETCONN_COPY);
158 if(err != ERR_OK){}
159 }
160 while(netbuf_next(buf) >= 0);
161 netbuf_delete(buf);
162 }
163 /* Close connection and discard connection identifier. */
164 netconn_delete(newconn);
165 }
166 }
167 }
168
169 /*
170 * TCP socket echo server
171 */
172 #define TCP_SOCKET_ECHO_PORT 700
173 #define TCP_SOCKET_BUFFER_SIZE 4096
174 rt_thread_t tcpecho_socket_tid = RT_NULL;
tcpecho_socket_entry(void * parameter)175 void tcpecho_socket_entry(void *parameter)
176 {
177 char *recv_data;
178 rt_uint32_t sin_size;
179 int sock = -1, connected, bytes_received;
180 struct sockaddr_in server_addr, client_addr;
181
182 recv_data = rt_malloc(TCP_SOCKET_BUFFER_SIZE);
183 if (recv_data == RT_NULL)
184 {
185 rt_kprintf("no memory\n");
186 goto _exit;
187 }
188
189 /* create a TCP socket */
190 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
191 {
192 rt_kprintf("create socket error\n");
193 goto _exit;
194 }
195
196 /* initialize server address */
197 server_addr.sin_family = AF_INET;
198 server_addr.sin_port = htons(TCP_SOCKET_ECHO_PORT);
199 server_addr.sin_addr.s_addr = INADDR_ANY;
200 rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero));
201
202 /* bind to server address */
203 if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
204 {
205 rt_kprintf("bind address failed\n");
206 goto _exit;
207 }
208
209 /* listen */
210 if (listen(sock, 5) == -1)
211 {
212 rt_kprintf("listen error\n");
213 goto _exit;
214 }
215
216 sin_size = sizeof(struct sockaddr_in);
217 while(1)
218 {
219 /* accept client connected */
220 connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
221 if (connected > 0)
222 {
223 int timeout;
224
225 /* set timeout option */
226 timeout = 5000; /* 5second */
227 setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
228
229 /* handle this client */
230 while (1)
231 {
232 /* receive data from this connection */
233 bytes_received = recv(connected,recv_data, TCP_SOCKET_BUFFER_SIZE, 0);
234 if (bytes_received <= 0)
235 {
236 rt_kprintf("close client connection, errno: %d\n",
237 rt_get_errno());
238 /* connection closed. */
239 lwip_close(connected);
240 break;
241 }
242
243 /* send data to client */
244 send(connected, recv_data, bytes_received, 0);
245 }
246 }
247 }
248
249 _exit:
250 /* close socket */
251 if (sock != -1) lwip_close(sock);
252 rt_free(recv_data);
253
254 return ;
255 }
256
257 /*
258 * NetIO TCP server
259 */
260
261 /* network test utilities entry */
net_test(void)262 void net_test(void)
263 {
264 /* start UDP echo server */
265 if (udpecho_tid == RT_NULL)
266 {
267 udpecho_tid = rt_thread_create("uecho",
268 udpecho_entry, RT_NULL,
269 512, RT_THREAD_PRIORITY_MAX/2, 5);
270 if (udpecho_tid != RT_NULL)
271 rt_thread_startup(udpecho_tid);
272 }
273 if (udpecho_socket_tid == RT_NULL)
274 {
275 udpecho_socket_tid = rt_thread_create("uecho_s",
276 udpecho_socket_entry, RT_NULL,
277 512, RT_THREAD_PRIORITY_MAX/2 + 1, 5);
278 if (udpecho_socket_tid != RT_NULL)
279 rt_thread_startup(udpecho_socket_tid);
280 }
281
282 if (tcpecho_tid == RT_NULL)
283 {
284 tcpecho_tid = rt_thread_create("techo",
285 tcpecho_entry, RT_NULL,
286 512, RT_THREAD_PRIORITY_MAX/2 + 2, 5);
287 if (tcpecho_tid != RT_NULL)
288 rt_thread_startup(tcpecho_tid);
289 }
290 if (tcpecho_socket_tid == RT_NULL)
291 {
292 tcpecho_socket_tid = rt_thread_create("techo_s",
293 tcpecho_socket_entry, RT_NULL,
294 512, RT_THREAD_PRIORITY_MAX/2 + 3, 5);
295 if (tcpecho_socket_tid != RT_NULL)
296 rt_thread_startup(tcpecho_socket_tid);
297 }
298 }
299 FINSH_FUNCTION_EXPORT(net_test, network test);
300
301