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; 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; 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; 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; 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 */ 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