net_test.c 8.5 KB
Newer Older
B
Bernard Xiong 已提交
1 2 3 4 5 6 7
/*
 * Net Test Utilities for RT-Thread
 */
#include <rtthread.h>
#include <finsh.h>
#include <lwip/api.h>
#include <lwip/sockets.h>
H
hduffddybz 已提交
8 9
#include <lwip/init.h>

B
Bernard Xiong 已提交
10 11 12 13 14 15 16
/* 
 * UDP echo server
 */
#define UDP_ECHO_PORT   7
rt_thread_t udpecho_tid = RT_NULL;
void udpecho_entry(void *parameter)
{
D
David Lin 已提交
17 18 19 20
    struct netconn *conn;
    struct netbuf *buf;
    struct ip_addr *addr;
    unsigned short port;
B
Bernard Xiong 已提交
21

D
David Lin 已提交
22 23 24 25 26 27 28
    conn = netconn_new(NETCONN_UDP);
    if(conn == NULL)
    {
        rt_kprintf("no memory error\n");
        return;
    }
    netconn_bind(conn, IP_ADDR_ANY, 7);
B
Bernard Xiong 已提交
29

D
David Lin 已提交
30 31
    while(1)
    {
B
Bernard Xiong 已提交
32
        /* received data to buffer */
H
hduffddybz 已提交
33
#if LWIP_VERSION_MINOR==3U 
D
David Lin 已提交
34
        buf = netconn_recv(conn);
H
hduffddybz 已提交
35
#else
D
David Lin 已提交
36
        netconn_recv(conn, &buf);
H
hduffddybz 已提交
37
#endif
D
David Lin 已提交
38 39 40 41 42 43
        if(buf == NULL)	
        {
            break;
        }
        addr = netbuf_fromaddr(buf);
        port = netbuf_fromport(buf);
B
Bernard Xiong 已提交
44

D
David Lin 已提交
45 46
        /* send the data to buffer */
        netconn_connect(conn, addr, port);
B
Bernard Xiong 已提交
47

D
David Lin 已提交
48
        /* reset address, and send to client */
H
hduffddybz 已提交
49
#if LWIP_VERSION_MINOR==3U 		
D
David Lin 已提交
50
        buf->addr = RT_NULL;
H
hduffddybz 已提交
51
#else
D
David Lin 已提交
52
        buf->addr = *IP_ADDR_ANY;
H
hduffddybz 已提交
53 54
#endif
		
D
David Lin 已提交
55
        netconn_send(conn, buf);
H
hduffddybz 已提交
56
		
D
David Lin 已提交
57 58 59 60 61
        /* release buffer */
        netbuf_delete(buf);
    }
	
    netconn_delete(conn);
B
Bernard Xiong 已提交
62 63 64 65 66 67 68 69 70
}
/*
 * 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)
{
D
David Lin 已提交
71 72 73 74 75
    int sock;
    int bytes_read;
    char *recv_data;
    rt_uint32_t addr_len;
    struct sockaddr_in server_addr, client_addr;
B
Bernard Xiong 已提交
76

D
David Lin 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89 90
    /* 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");
        return;
    }
    /* create a UDP socket */
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        rt_kprintf("create socket error\n");
        goto _exit;
    }
B
Bernard Xiong 已提交
91

D
David Lin 已提交
92 93 94 95 96
    /* 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));
B
Bernard Xiong 已提交
97

D
David Lin 已提交
98 99 100 101 102 103 104 105
    /* 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;
    }
B
Bernard Xiong 已提交
106

D
David Lin 已提交
107 108 109 110 111 112 113 114 115 116 117
    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);
    }
B
Bernard Xiong 已提交
118 119

_exit:
D
David Lin 已提交
120 121
    rt_free(recv_data);
    return;
B
Bernard Xiong 已提交
122 123 124 125 126 127 128 129 130
}

/*
 * TCP echo server
 */
#define TCP_ECHO_PORT   7
rt_thread_t tcpecho_tid = RT_NULL;
void tcpecho_entry(void *parameter)
{
D
David Lin 已提交
131 132
    struct netconn *conn, *newconn;
    err_t err;
B
Bernard Xiong 已提交
133

D
David Lin 已提交
134 135 136 137 138 139 140
    /* Create a new connection identifier. */
    conn = netconn_new(NETCONN_TCP);
    if(conn == NULL)
    {
        rt_kprintf("no memory error\n");
        return;
    }
B
Bernard Xiong 已提交
141

D
David Lin 已提交
142 143
    /* Bind connection to well known port number 7. */
    netconn_bind(conn, NULL, TCP_ECHO_PORT);
B
Bernard Xiong 已提交
144

D
David Lin 已提交
145 146
    /* Tell connection to go into listening mode. */
    netconn_listen(conn);
B
Bernard Xiong 已提交
147

D
David Lin 已提交
148 149 150
    while(1)
    {
        /* Grab new connection. */
H
hduffddybz 已提交
151
#if LWIP_VERSION_MINOR==3U 
D
David Lin 已提交
152 153
        newconn = netconn_accept(conn);
        if(newconn != NULL)
H
hduffddybz 已提交
154
#else
D
David Lin 已提交
155 156
        err = netconn_accept(conn, &newconn);
        if(err == ERR_OK)
H
hduffddybz 已提交
157
#endif
D
David Lin 已提交
158 159 160 161 162
        /* Process the new connection. */
        {
            struct netbuf *buf;
            void *data;
            u16_t len;
H
hduffddybz 已提交
163
#if LWIP_VERSION_MINOR==3U
D
David Lin 已提交
164
            while((buf = netconn_recv(newconn)) != NULL)
H
hduffddybz 已提交
165
#else
D
David Lin 已提交
166
            while((err = netconn_recv(newconn, &buf)) == ERR_OK)
H
hduffddybz 已提交
167
#endif
D
David Lin 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
            {
                do
                {
                    netbuf_data(buf, &data, &len);
                    err = netconn_write(newconn, data, len, NETCONN_COPY);
                    if(err != ERR_OK)
                    {
                        break;			    
                    }
                }while(netbuf_next(buf) >= 0);
		    
                netbuf_delete(buf);
            }
            /* Close connection and discard connection identifier. */
            netconn_delete(newconn);
        }
    }
	
    netconn_delete(conn);
B
Bernard Xiong 已提交
187 188 189 190 191 192 193 194 195 196
}

/*
 * 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)
{
D
David Lin 已提交
197 198 199 200
    char *recv_data;
    rt_uint32_t sin_size;
    int sock = -1, connected, bytes_received;
    struct sockaddr_in server_addr, client_addr;
B
Bernard Xiong 已提交
201

D
David Lin 已提交
202 203 204 205 206 207
    recv_data = rt_malloc(TCP_SOCKET_BUFFER_SIZE);
    if (recv_data == RT_NULL)
    {
        rt_kprintf("no memory\n");
        return;
    }
B
Bernard Xiong 已提交
208

D
David Lin 已提交
209 210 211 212 213 214
    /* create a TCP socket */
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        rt_kprintf("create socket error\n");
        goto _exit;
    }
B
Bernard Xiong 已提交
215

D
David Lin 已提交
216 217 218 219
    /* 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;
D
David Lin 已提交
220
    rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));
B
Bernard Xiong 已提交
221

D
David Lin 已提交
222 223 224 225 226 227
    /* bind to server address */
    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
    {
        rt_kprintf("bind address failed\n");
        goto _exit;
    }
B
Bernard Xiong 已提交
228

D
David Lin 已提交
229 230 231 232 233 234
    /* listen */
    if (listen(sock, 5) == -1)
    {
        rt_kprintf("listen error\n");
        goto _exit;
    }
B
Bernard Xiong 已提交
235

D
David Lin 已提交
236 237 238 239 240 241 242 243
    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;
B
Bernard Xiong 已提交
244
			
D
David Lin 已提交
245 246 247
            /* set timeout option */
            timeout = 5000; /* 5second */
            setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
B
Bernard Xiong 已提交
248

D
David Lin 已提交
249 250 251 252 253 254 255 256 257 258 259 260
            /* 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;
                }
B
Bernard Xiong 已提交
261

D
David Lin 已提交
262 263 264 265 266
                /* send data to client */
                send(connected, recv_data, bytes_received, 0);
            }
        }
    }
B
Bernard Xiong 已提交
267 268

_exit:
D
David Lin 已提交
269 270 271
    /* close socket */
    if (sock != -1) lwip_close(sock);
    rt_free(recv_data);
B
Bernard Xiong 已提交
272

D
David Lin 已提交
273
    return;
B
Bernard Xiong 已提交
274 275 276 277 278 279 280 281 282
}

/*
 * NetIO TCP server
 */

/* network test utilities entry */
void net_test(void)
{
D
David Lin 已提交
283 284 285 286 287 288 289 290 291 292 293 294 295
    /* 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);
        }
    }
B
Bernard Xiong 已提交
296

D
David Lin 已提交
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
    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);
    }
B
Bernard Xiong 已提交
334 335
}
FINSH_FUNCTION_EXPORT(net_test, network test);