Pārlūkot izejas kodu

[examples] update:
1. cleanup for posix dfs_net.
2. fixed recv buf overwrite.
3. format code.

aozima 7 gadi atpakaļ
vecāks
revīzija
e20fb2f5b2

+ 30 - 19
examples/network/chargen.c

@@ -1,7 +1,14 @@
 #include <rtthread.h>
-#include <sys/socket.h> 
-#include <sys/select.h>
-#include <dfs_posix.h> 
+#include <sys/socket.h>
+
+#ifdef RT_USING_DFS_NET
+#include <sys/select.h> // only dfs_net
+#include <dfs_posix.h>
+#else
+#define read        lwip_read
+#define write       lwip_write
+#endif /* RT_USING_DFS_NET */
+
 #include "netdb.h"
 
 #define MAX_SERV                 32         /* Maximum number of chargen services. Don't need too many */
@@ -52,16 +59,16 @@ static void chargen_thread(void *arg)
 
     if (bind(listenfd, (struct sockaddr *) &chargen_saddr, sizeof(chargen_saddr)) == -1)
         LWIP_ASSERT("chargen_thread(): Socket bind failed.", 0);
-	
+
     /* Put socket into listening mode */
     if (listen(listenfd, MAX_SERV) == -1)
         LWIP_ASSERT("chargen_thread(): Listen failed.", 0);
-	
+
 
     /* Wait forever for network input: This could be connections or data */
     for (;;)
     {
-        maxfdp1 = listenfd+1;
+        maxfdp1 = listenfd + 1;
 
         /* Determine what sockets need to be in readset */
         FD_ZERO(&readset);
@@ -78,7 +85,7 @@ static void chargen_thread(void *arg)
         /* Wait for data or a new connection */
         i = select(maxfdp1, &readset, &writeset, 0, 0);
 
-          if (i == 0) continue;
+        if (i == 0) continue;
 
         /* At least one descriptor is ready */
         if (FD_ISSET(listenfd, &readset))
@@ -89,8 +96,8 @@ static void chargen_thread(void *arg)
             if (p_charcb)
             {
                 p_charcb->socket = accept(listenfd,
-                                        (struct sockaddr *) &p_charcb->cliaddr,
-                                        &p_charcb->clilen);
+                                          (struct sockaddr *) &p_charcb->cliaddr,
+                                          &p_charcb->clilen);
                 if (p_charcb->socket < 0)
                     rt_free(p_charcb);
                 else
@@ -101,8 +108,8 @@ static void chargen_thread(void *arg)
                     p_charcb->nextchar = 0x21;
                 }
             }
-			else
-			{
+            else
+            {
                 /* No memory to accept connection. Just accept and then close */
                 int sock;
                 struct sockaddr cliaddr;
@@ -113,6 +120,7 @@ static void chargen_thread(void *arg)
                     closesocket(sock);
             }
         }
+
         /* Go through list of connected clients and process data */
         for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next)
         {
@@ -124,17 +132,19 @@ static void chargen_thread(void *arg)
                 if (do_read(p_charcb) < 0)
                     break;
             }
+
             if (FD_ISSET(p_charcb->socket, &writeset))
             {
                 char line[80];
                 char setchar = p_charcb->nextchar;
 
-                for( i = 0; i < 59; i++)
+                for (i = 0; i < 59; i++)
                 {
                     line[i] = setchar;
                     if (++setchar == 0x7f)
                         setchar = 0x21;
                 }
+
                 line[i] = 0;
                 strcat(line, "\n\r");
                 if (write(p_charcb->socket, line, strlen(line)) < 0)
@@ -142,6 +152,7 @@ static void chargen_thread(void *arg)
                     close_chargen(p_charcb);
                     break;
                 }
+
                 if (++p_charcb->nextchar == 0x7f)
                     p_charcb->nextchar = 0x21;
             }
@@ -202,19 +213,19 @@ static int do_read(struct charcb *p_charcb)
 
 void chargen_init(void)
 {
-	rt_thread_t chargen;
+    rt_thread_t chargen;
 
-	chargen = rt_thread_create(CHARGEN_THREAD_NAME,
-		chargen_thread, RT_NULL,
-		CHARGEN_THREAD_STACKSIZE,
-		CHARGEN_PRIORITY, 5);
-	if (chargen != RT_NULL) rt_thread_startup(chargen);
+    chargen = rt_thread_create(CHARGEN_THREAD_NAME,
+                               chargen_thread, RT_NULL,
+                               CHARGEN_THREAD_STACKSIZE,
+                               CHARGEN_PRIORITY, 5);
+    if (chargen != RT_NULL) rt_thread_startup(chargen);
 }
 #ifdef RT_USING_FINSH
 #include <finsh.h>
 void chargen()
 {
-	chargen_init();
+    chargen_init();
 }
 FINSH_FUNCTION_EXPORT(chargen, start chargen server);
 #endif

+ 7 - 9
examples/network/tcpclient.c

@@ -1,15 +1,12 @@
 #include <rtthread.h>
 
-//#include <lwip/netdb.h>   /* 为了解析主机名,需要包含netdb.h头文件 */
-//#include <lwip/sockets.h> /* 使用BSD socket,需要包含sockets.h头文件 */
-
-#include <sys/socket.h> /* 使用BSD socket,需要包含sockets.h头文件 */
+#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
 #include "netdb.h"
 
 #define BUFSZ   1024
 
 static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */
-void tcpclient(const char* url, int port)
+void tcpclient(const char *url, int port)
 {
     int ret;
     char *recv_data;
@@ -57,7 +54,7 @@ void tcpclient(const char* url, int port)
         return;
     }
 
-    while(1)
+    while (1)
     {
         /* 从sock连接中接收最大BUFSZ - 1字节数据 */
         bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
@@ -75,13 +72,14 @@ void tcpclient(const char* url, int port)
         {
             /* 打印recv函数返回值为0的警告信息 */
             rt_kprintf("\nReceived warning,recv function return 0.\r\n");
+
             continue;
         }
 
         /* 有接收到数据,把末端清零 */
         recv_data[bytes_received] = '\0';
 
-        if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
+        if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0)
         {
             /* 如果是首字母是q或Q,关闭这个连接 */
             closesocket(sock);
@@ -94,11 +92,11 @@ void tcpclient(const char* url, int port)
         else
         {
             /* 在控制终端显示收到的数据 */
-            rt_kprintf("\nReceived data = %s " , recv_data);
+            rt_kprintf("\nReceived data = %s ", recv_data);
         }
 
         /* 发送数据到sock连接 */
-        ret = send(sock,send_data,strlen(send_data), 0);
+        ret = send(sock, send_data, strlen(send_data), 0);
         if (ret < 0)
         {
             /* 接收失败,关闭这个连接 */

+ 9 - 8
examples/network/tcpsendpacket.c

@@ -1,8 +1,9 @@
 #include <rtthread.h>
-#include <lwip/netdb.h>   /* 为了解析主机名,需要包含netdb.h头文件 */
-#include <lwip/sockets.h> /* 使用BSD socket,需要包含sockets.h头文件 */
 
-void tcp_senddata(const char* url, int port, int length)
+#include <netdb.h>   /* 为了解析主机名,需要包含netdb.h头文件 */
+#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
+
+void tcp_senddata(const char *url, int port, int length)
 {
     struct hostent *host;
     int sock, err, result, timeout, index;
@@ -27,7 +28,7 @@ void tcp_senddata(const char* url, int port, int length)
 
     timeout = 100;
     /* 设置发送超时时间100ms */
-    lwip_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
+    setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
     /* 初始化预连接的服务端地址 */
     server_addr.sin_family = AF_INET;
     server_addr.sin_port = htons(port);
@@ -38,20 +39,20 @@ void tcp_senddata(const char* url, int port, int length)
     err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
     rt_kprintf("TCP thread connect error code: %d\n", err);
 
-    while(1)
+    while (1)
     {
         /* 发送数据到sock连接 */
         result = send(sock, buffer_ptr, length, MSG_DONTWAIT);
-        if(result < 0) //数据发送错误处理
+        if (result < 0) //数据发送错误处理
         {
             rt_kprintf("TCP thread send error: %d\n", result);
-            lwip_close(sock);
+            closesocket(sock);
 
             /* 关闭连接,重新创建连接 */
             rt_thread_delay(10);
 
             if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
-                rt_kprintf("TCP Socket error:%d\n",sock);
+                rt_kprintf("TCP Socket error:%d\n", sock);
 
             err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
             rt_kprintf("TCP thread connect error code: %d\n", err);

+ 132 - 125
examples/network/tcpserver.c

@@ -1,140 +1,147 @@
 #include <rtthread.h>
 
-//#include <lwip/sockets.h> /* 使用BSD Socket接口必须包含sockets.h这个头文件 */
-#include <sys/socket.h> /* 使用BSD socket,需要包含sockets.h头文件 */
+#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
 #include "netdb.h"
 
+#define BUFSZ       (1024)
+
 static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */
-void tcpserv(void* parameter)
+static void tcpserv(void *parameter)
 {
-   char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */
-   rt_uint32_t sin_size;
-   int sock, connected, bytes_received;
-   struct sockaddr_in server_addr, client_addr;
-   rt_bool_t stop = RT_FALSE; /* 停止标志 */
-   int ret;
-
-   recv_data = rt_malloc(1024); /* 分配接收用的数据缓冲 */
-   if (recv_data == RT_NULL)
-   {
-       rt_kprintf("No memory\n");
-       return;
-   }
-
-   /* 一个socket在使用前,需要预先创建出来,指定SOCK_STREAM为TCP的socket */
-   if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
-   {
-       /* 创建失败的错误处理 */
-       rt_kprintf("Socket error\n");
-
-       /* 释放已分配的接收缓冲 */
-       rt_free(recv_data);
-       return;
-   }
-
-   /* 初始化服务端地址 */
-   server_addr.sin_family = AF_INET;
-   server_addr.sin_port = htons(5000); /* 服务端工作的端口 */
-   server_addr.sin_addr.s_addr = INADDR_ANY;
-   rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero));
-
-   /* 绑定socket到服务端地址 */
-   if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
-   {
-       /* 绑定失败 */
-       rt_kprintf("Unable to bind\n");
-
-       /* 释放已分配的接收缓冲 */
-       rt_free(recv_data);
-       return;
-   }
-
-   /* 在socket上进行监听 */
-   if (listen(sock, 5) == -1)
-   {
-       rt_kprintf("Listen error\n");
-
-       /* release recv buffer */
-       rt_free(recv_data);
-       return;
-   }
-
-   rt_kprintf("\nTCPServer Waiting for client on port 5000...\n");
-   while(stop != RT_TRUE)
-   {
-       sin_size = sizeof(struct sockaddr_in);
-
-       /* 接受一个客户端连接socket的请求,这个函数调用是阻塞式的 */
-       connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
-       /* 返回的是连接成功的socket */
-
-       /* 接受返回的client_addr指向了客户端的地址信息 */
-       rt_kprintf("I got a connection from (%s , %d)\n",
-                  inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
-
-       /* 客户端连接的处理 */
-       while (1)
-       {
-           /* 发送数据到connected socket */
-           ret = send(connected, send_data, strlen(send_data), 0);
-           if (ret < 0)
-           {
+    char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */
+    socklen_t sin_size;
+    int sock, connected, bytes_received;
+    struct sockaddr_in server_addr, client_addr;
+    rt_bool_t stop = RT_FALSE; /* 停止标志 */
+    int ret;
+
+    recv_data = rt_malloc(BUFSZ + 1); /* 分配接收用的数据缓冲 */
+    if (recv_data == RT_NULL)
+    {
+        rt_kprintf("No memory\n");
+        return;
+    }
+
+    /* 一个socket在使用前,需要预先创建出来,指定SOCK_STREAM为TCP的socket */
+    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+    {
+        /* 创建失败的错误处理 */
+        rt_kprintf("Socket error\n");
+
+        /* 释放已分配的接收缓冲 */
+        rt_free(recv_data);
+        return;
+    }
+
+    /* 初始化服务端地址 */
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_port = htons(5000); /* 服务端工作的端口 */
+    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)
+    {
+        /* 绑定失败 */
+        rt_kprintf("Unable to bind\n");
+
+        /* 释放已分配的接收缓冲 */
+        rt_free(recv_data);
+        return;
+    }
+
+    /* 在socket上进行监听 */
+    if (listen(sock, 5) == -1)
+    {
+        rt_kprintf("Listen error\n");
+
+        /* release recv buffer */
+        rt_free(recv_data);
+        return;
+    }
+
+    rt_kprintf("\nTCPServer Waiting for client on port 5000...\n");
+    while (stop != RT_TRUE)
+    {
+        sin_size = sizeof(struct sockaddr_in);
+
+        /* 接受一个客户端连接socket的请求,这个函数调用是阻塞式的 */
+        connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
+        /* 返回的是连接成功的socket */
+        if (connected < 0)
+        {
+            rt_kprintf("accept connection failed! errno = %d\n", errno);
+            continue;
+        }
+
+        /* 接受返回的client_addr指向了客户端的地址信息 */
+        rt_kprintf("I got a connection from (%s , %d)\n",
+                   inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
+
+        /* 客户端连接的处理 */
+        while (1)
+        {
+            /* 发送数据到connected socket */
+            ret = send(connected, send_data, strlen(send_data), 0);
+            if (ret < 0)
+            {
                 /* 发送失败,关闭这个连接 */
                 closesocket(connected);
                 rt_kprintf("\nsend error,close the socket.\r\n");
                 break;
-           }
-           else if (ret == 0)
-           {
+            }
+            else if (ret == 0)
+            {
                 /* 打印send函数返回值为0的警告信息 */
                 rt_kprintf("\n Send warning,send function return 0.\r\n");
-           }
-
-           /* 从connected socket中接收数据,接收buffer是1024大小,但并不一定能够收到1024大小的数据 */
-           bytes_received = recv(connected,recv_data, 1024, 0);
-           if (bytes_received < 0)
-           {
-               /* 接收失败,关闭这个connected socket */
-               closesocket(connected);
-               break;
-           }
-           else if (bytes_received == 0)
-           {
-               /* 打印recv函数返回值为0的警告信息 */
-               rt_kprintf("\nReceived warning,recv function return 0.\r\n");
-               continue;
-           }
-
-           /* 有接收到数据,把末端清零 */
-           recv_data[bytes_received] = '\0';
-           if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
-           {
-               /* 如果是首字母是q或Q,关闭这个连接 */
-               closesocket(connected);
-               break;
-           }
-           else if (strcmp(recv_data, "exit") == 0)
-           {
-               /* 如果接收的是exit,则关闭整个服务端 */
-               closesocket(connected);
-               stop = RT_TRUE;
-               break;
-           }
-           else
-           {
-               /* 在控制终端显示收到的数据 */
-               rt_kprintf("RECEIVED DATA = %s \n" , recv_data);
-           }
-       }
-   }
-
-   /* 退出服务 */
-   closesocket(sock);
-
-   /* 释放接收缓冲 */
-   rt_free(recv_data);
-
-   return ;
+            }
+
+            /* 从connected socket中接收数据,接收buffer是1024大小,但并不一定能够收到1024大小的数据 */
+            bytes_received = recv(connected, recv_data, BUFSZ, 0);
+            if (bytes_received < 0)
+            {
+                /* 接收失败,关闭这个connected socket */
+                closesocket(connected);
+                break;
+            }
+            else if (bytes_received == 0)
+            {
+                /* 打印recv函数返回值为0的警告信息 */
+                rt_kprintf("\nReceived warning,recv function return 0.\r\n");
+                closesocket(connected);
+                break;
+            }
+
+            /* 有接收到数据,把末端清零 */
+            recv_data[bytes_received] = '\0';
+            if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0)
+            {
+                /* 如果是首字母是q或Q,关闭这个连接 */
+                closesocket(connected);
+                break;
+            }
+            else if (strcmp(recv_data, "exit") == 0)
+            {
+                /* 如果接收的是exit,则关闭整个服务端 */
+                closesocket(connected);
+                stop = RT_TRUE;
+                break;
+            }
+            else
+            {
+                /* 在控制终端显示收到的数据 */
+                rt_kprintf("RECEIVED DATA = %s \n", recv_data);
+            }
+        }
+    }
+
+    /* 退出服务 */
+    closesocket(sock);
+
+    /* 释放接收缓冲 */
+    rt_free(recv_data);
+
+    return ;
 }
 
 #ifdef RT_USING_FINSH

+ 37 - 37
examples/network/udpclient.c

@@ -5,44 +5,44 @@
 #include "netdb.h"
 
 const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* 发送用到的数据 */
-void udpclient(const char* url, int port, int count)
+void udpclient(const char *url, int port, int count)
 {
-   int sock;
-   struct hostent *host;
-   struct sockaddr_in server_addr;
-
-   /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
-   host= (struct hostent *) gethostbyname(url);
-
-   /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */
-   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
-   {
-       rt_kprintf("Socket error\n");
-       return;
-   }
-
-   /* 初始化预连接的服务端地址 */
-   server_addr.sin_family = AF_INET;
-   server_addr.sin_port = htons(port);
-   server_addr.sin_addr = *((struct in_addr *)host->h_addr);
-   rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
-
-   /* 总计发送count次数据 */
-   while (count)
-   {
-       /* 发送数据到服务远端 */
-       sendto(sock, send_data, strlen(send_data), 0,
-              (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
-
-       /* 线程休眠一段时间 */
-       rt_thread_delay(50);
-
-       /* 计数值减一 */
-       count --;
-   }
-
-   /* 关闭这个socket */
-   closesocket(sock);
+    int sock;
+    struct hostent *host;
+    struct sockaddr_in server_addr;
+
+    /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
+    host = (struct hostent *) gethostbyname(url);
+
+    /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+    {
+        rt_kprintf("Socket error\n");
+        return;
+    }
+
+    /* 初始化预连接的服务端地址 */
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_port = htons(port);
+    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
+    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
+
+    /* 总计发送count次数据 */
+    while (count)
+    {
+        /* 发送数据到服务远端 */
+        sendto(sock, send_data, strlen(send_data), 0,
+               (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
+
+        /* 线程休眠一段时间 */
+        rt_thread_delay(50);
+
+        /* 计数值减一 */
+        count --;
+    }
+
+    /* 关闭这个socket */
+    closesocket(sock);
 }
 
 #ifdef RT_USING_FINSH

+ 76 - 77
examples/network/udpserver.c

@@ -1,85 +1,84 @@
 #include <rtthread.h>
-//#include <lwip/sockets.h> /* 使用BSD socket,需要包含sockets.h头文件 */
-#include <sys/socket.h> /* 使用BSD socket,需要包含sockets.h头文件 */
-#include "netdb.h"
 
+#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
+#include "netdb.h"
 
-#define BUFSZ	1024
+#define BUFSZ   1024
 
-void udpserv(void* paramemter)
+static void udpserv(void *paramemter)
 {
-   int sock;
-   int bytes_read;
-   char *recv_data;
-   rt_uint32_t addr_len;
-   struct sockaddr_in server_addr, client_addr;
-
-   /* 分配接收用的数据缓冲 */
-   recv_data = rt_malloc(BUFSZ);
-   if (recv_data == RT_NULL)
-   {
-       /* 分配内存失败,返回 */
-       rt_kprintf("No memory\n");
-       return;
-   }
-
-   /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */
-   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
-   {
-       rt_kprintf("Socket error\n");
-
-       /* 释放接收用的数据缓冲 */
-       rt_free(recv_data);
-       return;
-   }
-
-   /* 初始化服务端地址 */
-   server_addr.sin_family = AF_INET;
-   server_addr.sin_port = htons(5000);
-   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)
-   {
-       /* 绑定地址失败 */
-       rt_kprintf("Bind error\n");
-
-       /* 释放接收用的数据缓冲 */
-       rt_free(recv_data);
-       return;
-   }
-
-   addr_len = sizeof(struct sockaddr);
-   rt_kprintf("UDPServer Waiting for client on port 5000...\n");
-
-   while (1)
-   {
-       /* 从sock中收取最大BUFSZ - 1字节数据 */
-       bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0,
-                             (struct sockaddr *)&client_addr, &addr_len);
-       /* UDP不同于TCP,它基本不会出现收取的数据失败的情况,除非设置了超时等待 */
-
-       recv_data[bytes_read] = '\0'; /* 把末端清零 */
-
-       /* 输出接收的数据 */
-       rt_kprintf("\n(%s , %d) said : ",inet_ntoa(client_addr.sin_addr),
-                  ntohs(client_addr.sin_port));
-       rt_kprintf("%s", recv_data);
-
-       /* 如果接收数据是exit,退出 */
-       if (strcmp(recv_data, "exit") == 0)
-       {
-           closesocket(sock);
-
-           /* 释放接收用的数据缓冲 */
-           rt_free(recv_data);
-           break;
-       }
-   }
-
-   return;
+    int sock;
+    int bytes_read;
+    char *recv_data;
+    socklen_t addr_len;
+    struct sockaddr_in server_addr, client_addr;
+
+    /* 分配接收用的数据缓冲 */
+    recv_data = rt_malloc(BUFSZ);
+    if (recv_data == RT_NULL)
+    {
+        /* 分配内存失败,返回 */
+        rt_kprintf("No memory\n");
+        return;
+    }
+
+    /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+    {
+        rt_kprintf("Socket error\n");
+
+        /* 释放接收用的数据缓冲 */
+        rt_free(recv_data);
+        return;
+    }
+
+    /* 初始化服务端地址 */
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_port = htons(5000);
+    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)
+    {
+        /* 绑定地址失败 */
+        rt_kprintf("Bind error\n");
+
+        /* 释放接收用的数据缓冲 */
+        rt_free(recv_data);
+        return;
+    }
+
+    addr_len = sizeof(struct sockaddr);
+    rt_kprintf("UDPServer Waiting for client on port 5000...\n");
+
+    while (1)
+    {
+        /* 从sock中收取最大BUFSZ - 1字节数据 */
+        bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0,
+                              (struct sockaddr *)&client_addr, &addr_len);
+        /* UDP不同于TCP,它基本不会出现收取的数据失败的情况,除非设置了超时等待 */
+
+        recv_data[bytes_read] = '\0'; /* 把末端清零 */
+
+        /* 输出接收的数据 */
+        rt_kprintf("\n(%s , %d) said : ", inet_ntoa(client_addr.sin_addr),
+                   ntohs(client_addr.sin_port));
+        rt_kprintf("%s", recv_data);
+
+        /* 如果接收数据是exit,退出 */
+        if (strcmp(recv_data, "exit") == 0)
+        {
+            closesocket(sock);
+
+            /* 释放接收用的数据缓冲 */
+            rt_free(recv_data);
+            break;
+        }
+    }
+
+    return;
 }
 
 #ifdef RT_USING_FINSH