301 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			301 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Net Test Utilities for RT-Thread
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#include <rtthread.h>
							 | 
						||
| 
								 | 
							
								#include <finsh.h>
							 | 
						||
| 
								 | 
							
								#include <lwip/api.h>
							 | 
						||
| 
								 | 
							
								#include <lwip/sockets.h>
							 | 
						||
| 
								 | 
							
								#include <lwip/init.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* 
							 | 
						||
| 
								 | 
							
								 * UDP echo server
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#define UDP_ECHO_PORT   7
							 | 
						||
| 
								 | 
							
								rt_thread_t udpecho_tid = RT_NULL;
							 | 
						||
| 
								 | 
							
								void udpecho_entry(void *parameter)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									struct netconn *conn;
							 | 
						||
| 
								 | 
							
									struct netbuf *buf;
							 | 
						||
| 
								 | 
							
									struct ip_addr *addr;
							 | 
						||
| 
								 | 
							
									unsigned short port;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									conn = netconn_new(NETCONN_UDP);
							 | 
						||
| 
								 | 
							
									netconn_bind(conn, IP_ADDR_ANY, 7);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									while(1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								        /* received data to buffer */
							 | 
						||
| 
								 | 
							
								#if LWIP_VERSION_MINOR==3U 
							 | 
						||
| 
								 | 
							
										buf = netconn_recv(conn);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										netconn_recv(conn, &buf);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										addr = netbuf_fromaddr(buf);
							 | 
						||
| 
								 | 
							
										port = netbuf_fromport(buf);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   		 /* send the data to buffer */
							 | 
						||
| 
								 | 
							
										netconn_connect(conn, addr, port);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* reset address, and send to client */
							 | 
						||
| 
								 | 
							
								#if LWIP_VERSION_MINOR==3U 		
							 | 
						||
| 
								 | 
							
										buf->addr = RT_NULL;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										buf->addr = *IP_ADDR_ANY;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										netconn_send(conn, buf);
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/* release buffer */
							 | 
						||
| 
								 | 
							
										netbuf_delete(buf);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * UDP socket echo server
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#define UDP_SOCKET_ECHO_PORT	700
							 | 
						||
| 
								 | 
							
								#define UDP_SOCKET_BUFFER_SIZE	4096
							 | 
						||
| 
								 | 
							
								rt_thread_t udpecho_socket_tid = RT_NULL;
							 | 
						||
| 
								 | 
							
								void udpecho_socket_entry(void *parameter)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int sock;
							 | 
						||
| 
								 | 
							
									int bytes_read;
							 | 
						||
| 
								 | 
							
									char *recv_data;
							 | 
						||
| 
								 | 
							
									rt_uint32_t addr_len;
							 | 
						||
| 
								 | 
							
									struct sockaddr_in server_addr, client_addr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* allocate the data buffer */
							 | 
						||
| 
								 | 
							
									recv_data = rt_malloc(UDP_SOCKET_BUFFER_SIZE);
							 | 
						||
| 
								 | 
							
									if (recv_data == RT_NULL)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* no memory yet */
							 | 
						||
| 
								 | 
							
										rt_kprintf("no memory\n");
							 | 
						||
| 
								 | 
							
										goto _exit;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									/* create a UDP socket */
							 | 
						||
| 
								 | 
							
									if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										rt_kprintf("create socket error\n");
							 | 
						||
| 
								 | 
							
										goto _exit;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* initialize server address */
							 | 
						||
| 
								 | 
							
									server_addr.sin_family = AF_INET;
							 | 
						||
| 
								 | 
							
									server_addr.sin_port = htons(UDP_SOCKET_ECHO_PORT);
							 | 
						||
| 
								 | 
							
									server_addr.sin_addr.s_addr = INADDR_ANY;
							 | 
						||
| 
								 | 
							
									rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* bind socket to server address */
							 | 
						||
| 
								 | 
							
									if (bind(sock,(struct sockaddr *)&server_addr,
							 | 
						||
| 
								 | 
							
											sizeof(struct sockaddr)) == -1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* bind failed */
							 | 
						||
| 
								 | 
							
										rt_kprintf("bind error\n");
							 | 
						||
| 
								 | 
							
										goto _exit;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									addr_len = sizeof(struct sockaddr);
							 | 
						||
| 
								 | 
							
									while (1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* try to receive from UDP socket */
							 | 
						||
| 
								 | 
							
										bytes_read = recvfrom(sock, recv_data, UDP_SOCKET_BUFFER_SIZE, 0,
							 | 
						||
| 
								 | 
							
															 (struct sockaddr *)&client_addr, &addr_len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* send back */
							 | 
						||
| 
								 | 
							
										sendto(sock, recv_data, bytes_read, 0,
							 | 
						||
| 
								 | 
							
											(struct sockaddr *)&client_addr, addr_len);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_exit:
							 | 
						||
| 
								 | 
							
									rt_free(recv_data);
							 | 
						||
| 
								 | 
							
									return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * TCP echo server
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#define TCP_ECHO_PORT   7
							 | 
						||
| 
								 | 
							
								rt_thread_t tcpecho_tid = RT_NULL;
							 | 
						||
| 
								 | 
							
								void tcpecho_entry(void *parameter)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									struct netconn *conn, *newconn;
							 | 
						||
| 
								 | 
							
									err_t err;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Create a new connection identifier. */
							 | 
						||
| 
								 | 
							
									conn = netconn_new(NETCONN_TCP);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Bind connection to well known port number 7. */
							 | 
						||
| 
								 | 
							
									netconn_bind(conn, NULL, TCP_ECHO_PORT);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Tell connection to go into listening mode. */
							 | 
						||
| 
								 | 
							
									netconn_listen(conn);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									while(1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* Grab new connection. */
							 | 
						||
| 
								 | 
							
								#if LWIP_VERSION_MINOR==3U 
							 | 
						||
| 
								 | 
							
										newconn = netconn_accept(conn);
							 | 
						||
| 
								 | 
							
										if(newconn != NULL)
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										err = netconn_accept(conn, &newconn);
							 | 
						||
| 
								 | 
							
										if(err == ERR_OK)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
										/* Process the new connection. */
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											struct netbuf *buf;
							 | 
						||
| 
								 | 
							
											void *data;
							 | 
						||
| 
								 | 
							
											u16_t len;
							 | 
						||
| 
								 | 
							
								#if LWIP_VERSION_MINOR==3U
							 | 
						||
| 
								 | 
							
											while((buf = netconn_recv(newconn)) != NULL)
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
											while((err = netconn_recv(newconn, &buf)) == ERR_OK)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												do
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													netbuf_data(buf, &data, &len);
							 | 
						||
| 
								 | 
							
													err = netconn_write(newconn, data, len, NETCONN_COPY);
							 | 
						||
| 
								 | 
							
													if(err != ERR_OK){}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												while(netbuf_next(buf) >= 0);
							 | 
						||
| 
								 | 
							
												netbuf_delete(buf);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											/* Close connection and discard connection identifier. */
							 | 
						||
| 
								 | 
							
											netconn_delete(newconn);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * TCP socket echo server
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#define TCP_SOCKET_ECHO_PORT	700
							 | 
						||
| 
								 | 
							
								#define TCP_SOCKET_BUFFER_SIZE	4096
							 | 
						||
| 
								 | 
							
								rt_thread_t tcpecho_socket_tid = RT_NULL;
							 | 
						||
| 
								 | 
							
								void tcpecho_socket_entry(void *parameter)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   char *recv_data;
							 | 
						||
| 
								 | 
							
								   rt_uint32_t sin_size;
							 | 
						||
| 
								 | 
							
								   int sock = -1, connected, bytes_received;
							 | 
						||
| 
								 | 
							
								   struct sockaddr_in server_addr, client_addr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									recv_data = rt_malloc(TCP_SOCKET_BUFFER_SIZE);
							 | 
						||
| 
								 | 
							
									if (recv_data == RT_NULL)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										rt_kprintf("no memory\n");
							 | 
						||
| 
								 | 
							
										goto _exit;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* create a TCP socket */
							 | 
						||
| 
								 | 
							
									if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										rt_kprintf("create socket error\n");
							 | 
						||
| 
								 | 
							
										goto _exit;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* initialize server address */
							 | 
						||
| 
								 | 
							
									server_addr.sin_family = AF_INET;
							 | 
						||
| 
								 | 
							
									server_addr.sin_port = htons(TCP_SOCKET_ECHO_PORT);
							 | 
						||
| 
								 | 
							
									server_addr.sin_addr.s_addr = INADDR_ANY;
							 | 
						||
| 
								 | 
							
									rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* bind to server address */
							 | 
						||
| 
								 | 
							
									if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										rt_kprintf("bind address failed\n");
							 | 
						||
| 
								 | 
							
										goto _exit;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* listen */
							 | 
						||
| 
								 | 
							
									if (listen(sock, 5) == -1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										rt_kprintf("listen error\n");
							 | 
						||
| 
								 | 
							
										goto _exit;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									sin_size = sizeof(struct sockaddr_in);
							 | 
						||
| 
								 | 
							
									while(1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* accept client connected */
							 | 
						||
| 
								 | 
							
										connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
							 | 
						||
| 
								 | 
							
										if (connected > 0)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											int timeout;
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											/* set timeout option */
							 | 
						||
| 
								 | 
							
											timeout = 5000; /* 5second */
							 | 
						||
| 
								 | 
							
											setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* handle this client */
							 | 
						||
| 
								 | 
							
											while (1)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* receive data from this connection */
							 | 
						||
| 
								 | 
							
												bytes_received = recv(connected,recv_data, TCP_SOCKET_BUFFER_SIZE, 0);
							 | 
						||
| 
								 | 
							
												if (bytes_received <= 0)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													rt_kprintf("close client connection, errno: %d\n", 
							 | 
						||
| 
								 | 
							
														rt_get_errno());
							 | 
						||
| 
								 | 
							
													/* connection closed. */
							 | 
						||
| 
								 | 
							
													lwip_close(connected);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* send data to client */
							 | 
						||
| 
								 | 
							
												send(connected, recv_data, bytes_received, 0);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_exit:
							 | 
						||
| 
								 | 
							
									/* close socket */
							 | 
						||
| 
								 | 
							
									if (sock != -1) lwip_close(sock);
							 | 
						||
| 
								 | 
							
									rt_free(recv_data);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return ;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * NetIO TCP server
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* network test utilities entry */
							 | 
						||
| 
								 | 
							
								void net_test(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* start UDP echo server */
							 | 
						||
| 
								 | 
							
									if (udpecho_tid == RT_NULL)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										udpecho_tid = rt_thread_create("uecho",
							 | 
						||
| 
								 | 
							
																	udpecho_entry, RT_NULL,
							 | 
						||
| 
								 | 
							
																	512, RT_THREAD_PRIORITY_MAX/2, 5);
							 | 
						||
| 
								 | 
							
										if (udpecho_tid != RT_NULL)
							 | 
						||
| 
								 | 
							
											rt_thread_startup(udpecho_tid);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (udpecho_socket_tid == RT_NULL)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										udpecho_socket_tid = rt_thread_create("uecho_s",
							 | 
						||
| 
								 | 
							
																	udpecho_socket_entry, RT_NULL,
							 | 
						||
| 
								 | 
							
																	512, RT_THREAD_PRIORITY_MAX/2 + 1, 5);
							 | 
						||
| 
								 | 
							
										if (udpecho_socket_tid != RT_NULL)
							 | 
						||
| 
								 | 
							
											rt_thread_startup(udpecho_socket_tid);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (tcpecho_tid == RT_NULL)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										tcpecho_tid = rt_thread_create("techo",
							 | 
						||
| 
								 | 
							
																	tcpecho_entry, RT_NULL,
							 | 
						||
| 
								 | 
							
																	512, RT_THREAD_PRIORITY_MAX/2 + 2, 5);
							 | 
						||
| 
								 | 
							
										if (tcpecho_tid != RT_NULL)
							 | 
						||
| 
								 | 
							
											rt_thread_startup(tcpecho_tid);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (tcpecho_socket_tid == RT_NULL)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										tcpecho_socket_tid = rt_thread_create("techo_s",
							 | 
						||
| 
								 | 
							
																	tcpecho_socket_entry, RT_NULL,
							 | 
						||
| 
								 | 
							
																	512, RT_THREAD_PRIORITY_MAX/2 + 3, 5);
							 | 
						||
| 
								 | 
							
										if (tcpecho_socket_tid != RT_NULL)
							 | 
						||
| 
								 | 
							
											rt_thread_startup(tcpecho_socket_tid);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								FINSH_FUNCTION_EXPORT(net_test, network test);
							 | 
						||
| 
								 | 
							
								
							 |