diff --git a/examples/network/chargen.c b/examples/network/chargen.c new file mode 100644 index 0000000000000000000000000000000000000000..f6a2879cbd078c077d59436d9056f912c3a42355 --- /dev/null +++ b/examples/network/chargen.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include "netdb.h" + +#define MAX_SERV 32 /* Maximum number of chargen services. Don't need too many */ +#define CHARGEN_THREAD_NAME "chargen" +#if RT_THREAD_PRIORITY_MAX == 32 +#define CHARGEN_PRIORITY 20 /* Really low priority */ +#else +#define CHARGEN_PRIORITY 200 /* Really low priority */ +#endif +#define CHARGEN_THREAD_STACKSIZE 1024 +struct charcb +{ + struct charcb *next; + int socket; + struct sockaddr_in cliaddr; + socklen_t clilen; + char nextchar; +}; + +static struct charcb *charcb_list = 0; +static int do_read(struct charcb *p_charcb); +static void close_chargen(struct charcb *p_charcb); +extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); + +/************************************************************** + * void chargen_thread(void *arg) + * + * chargen task. This server will wait for connections on well + * known TCP port number: 19. For every connection, the server will + * write as much data as possible to the tcp port. + **************************************************************/ +static void chargen_thread(void *arg) +{ + int listenfd; + struct sockaddr_in chargen_saddr; + fd_set readset; + fd_set writeset; + int i, maxfdp1; + struct charcb *p_charcb; + + /* First acquire our socket for listening for connections */ + listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + LWIP_ASSERT("chargen_thread(): Socket create failed.", listenfd >= 0); + memset(&chargen_saddr, 0, sizeof(chargen_saddr)); + chargen_saddr.sin_family = AF_INET; + chargen_saddr.sin_addr.s_addr = htonl(INADDR_ANY); + chargen_saddr.sin_port = htons(19); // Chargen server port + + 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; + + /* Determine what sockets need to be in readset */ + FD_ZERO(&readset); + FD_ZERO(&writeset); + FD_SET(listenfd, &readset); + for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) + { + if (maxfdp1 < p_charcb->socket + 1) + maxfdp1 = p_charcb->socket + 1; + FD_SET(p_charcb->socket, &readset); + FD_SET(p_charcb->socket, &writeset); + } + + /* Wait for data or a new connection */ + i = select(maxfdp1, &readset, &writeset, 0, 0); + + if (i == 0) continue; + + /* At least one descriptor is ready */ + if (FD_ISSET(listenfd, &readset)) + { + /* We have a new connection request!!! */ + /* Lets create a new control block */ + p_charcb = (struct charcb *)rt_calloc(1, sizeof(struct charcb)); + if (p_charcb) + { + p_charcb->socket = accept(listenfd, + (struct sockaddr *) &p_charcb->cliaddr, + &p_charcb->clilen); + if (p_charcb->socket < 0) + rt_free(p_charcb); + else + { + /* Keep this tecb in our list */ + p_charcb->next = charcb_list; + charcb_list = p_charcb; + p_charcb->nextchar = 0x21; + } + } + else + { + /* No memory to accept connection. Just accept and then close */ + int sock; + struct sockaddr cliaddr; + socklen_t clilen; + + sock = accept(listenfd, &cliaddr, &clilen); + if (sock >= 0) + closesocket(sock); + } + } + /* Go through list of connected clients and process data */ + for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) + { + if (FD_ISSET(p_charcb->socket, &readset)) + { + /* This socket is ready for reading. This could be because someone typed + * some characters or it could be because the socket is now closed. Try reading + * some data to see. */ + 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++) + { + line[i] = setchar; + if (++setchar == 0x7f) + setchar = 0x21; + } + line[i] = 0; + strcat(line, "\n\r"); + if (write(p_charcb->socket, line, strlen(line)) < 0) + { + close_chargen(p_charcb); + break; + } + if (++p_charcb->nextchar == 0x7f) + p_charcb->nextchar = 0x21; + } + } + } +} + +/************************************************************** + * void close_chargen(struct charcb *p_charcb) + * + * Close the socket and remove this charcb from the list. + **************************************************************/ +static void close_chargen(struct charcb *p_charcb) +{ + struct charcb *p_search_charcb; + + /* Either an error or tcp connection closed on other + * end. Close here */ + closesocket(p_charcb->socket); + + /* Free charcb */ + if (charcb_list == p_charcb) + charcb_list = p_charcb->next; + else + for (p_search_charcb = charcb_list; p_search_charcb; p_search_charcb = p_search_charcb->next) + { + if (p_search_charcb->next == p_charcb) + { + p_search_charcb->next = p_charcb->next; + break; + } + } + + rt_free(p_charcb); +} + +/************************************************************** + * void do_read(struct charcb *p_charcb) + * + * Socket definitely is ready for reading. Read a buffer from the socket and + * discard the data. If no data is read, then the socket is closed and the + * charcb is removed from the list and freed. + **************************************************************/ +static int do_read(struct charcb *p_charcb) +{ + char buffer[80]; + int readcount; + + /* Read some data */ + readcount = read(p_charcb->socket, &buffer, 80); + if (readcount <= 0) + { + close_chargen(p_charcb); + return -1; + } + return 0; +} + +void chargen_init(void) +{ + 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); +} +#ifdef RT_USING_FINSH +#include +void chargen() +{ + chargen_init(); +} +FINSH_FUNCTION_EXPORT(chargen, start chargen server); +#endif diff --git a/examples/network/tcpclient.c b/examples/network/tcpclient.c index c7a53c609fa465df007816ffdc07b1447437f46b..a8a9d2959c08b77be4528281fbb5dc64989de5cf 100644 --- a/examples/network/tcpclient.c +++ b/examples/network/tcpclient.c @@ -1,7 +1,10 @@ #include -#include /* 为了解析主机名,需要包含netdb.h头文件 */ -#include /* 使用BSD socket,需要包含sockets.h头文件 */ +//#include /* 为了解析主机名,需要包含netdb.h头文件 */ +//#include /* 使用BSD socket,需要包含sockets.h头文件 */ + +#include /* 使用BSD socket,需要包含sockets.h头文件 */ +#include "netdb.h" #define BUFSZ 1024 @@ -47,7 +50,7 @@ void tcpclient(const char* url, int port) { /* 连接失败 */ rt_kprintf("Connect fail!\n"); - lwip_close(sock); + closesocket(sock); /*释放接收缓冲 */ rt_free(recv_data); @@ -61,7 +64,7 @@ void tcpclient(const char* url, int port) if (bytes_received < 0) { /* 接收失败,关闭这个连接 */ - lwip_close(sock); + closesocket(sock); rt_kprintf("\nreceived error,close the socket.\r\n"); /* 释放接收缓冲 */ @@ -81,7 +84,7 @@ void tcpclient(const char* url, int port) if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0) { /* 如果是首字母是q或Q,关闭这个连接 */ - lwip_close(sock); + closesocket(sock); rt_kprintf("\n got a 'q' or 'Q',close the socket.\r\n"); /* 释放接收缓冲 */ @@ -99,7 +102,7 @@ void tcpclient(const char* url, int port) if (ret < 0) { /* 接收失败,关闭这个连接 */ - lwip_close(sock); + closesocket(sock); rt_kprintf("\nsend error,close the socket.\r\n"); rt_free(recv_data); diff --git a/examples/network/tcpserver.c b/examples/network/tcpserver.c index c08949ea8335f9e3a35f97c08251eb0f9d95eac9..f07d2cd0e260f769ecb1163c255fe714f2368e8a 100644 --- a/examples/network/tcpserver.c +++ b/examples/network/tcpserver.c @@ -1,5 +1,8 @@ #include -#include /* 使用BSD Socket接口必须包含sockets.h这个头文件 */ + +//#include /* 使用BSD Socket接口必须包含sockets.h这个头文件 */ +#include /* 使用BSD socket,需要包含sockets.h头文件 */ +#include "netdb.h" static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */ void tcpserv(void* parameter) @@ -77,7 +80,7 @@ void tcpserv(void* parameter) if (ret < 0) { /* 发送失败,关闭这个连接 */ - lwip_close(connected); + closesocket(connected); rt_kprintf("\nsend error,close the socket.\r\n"); break; } @@ -92,7 +95,7 @@ void tcpserv(void* parameter) if (bytes_received < 0) { /* 接收失败,关闭这个connected socket */ - lwip_close(connected); + closesocket(connected); break; } else if (bytes_received == 0) @@ -107,13 +110,13 @@ void tcpserv(void* parameter) if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0) { /* 如果是首字母是q或Q,关闭这个连接 */ - lwip_close(connected); + closesocket(connected); break; } else if (strcmp(recv_data, "exit") == 0) { /* 如果接收的是exit,则关闭整个服务端 */ - lwip_close(connected); + closesocket(connected); stop = RT_TRUE; break; } @@ -126,7 +129,7 @@ void tcpserv(void* parameter) } /* 退出服务 */ - lwip_close(sock); + closesocket(sock); /* 释放接收缓冲 */ rt_free(recv_data); diff --git a/examples/network/udpclient.c b/examples/network/udpclient.c index 50e0d39784ddfd5f7cbd22673ca3fd7303d46ea0..c19a25fa6c1af6d09c7c7d0dfc45f4818bfdd65b 100644 --- a/examples/network/udpclient.c +++ b/examples/network/udpclient.c @@ -1,6 +1,8 @@ #include -#include /* 为了解析主机名,需要包含netdb.h头文件 */ -#include /* 使用BSD socket,需要包含sockets.h头文件 */ +//#include /* 为了解析主机名,需要包含netdb.h头文件 */ +//#include /* 使用BSD socket,需要包含sockets.h头文件 */ +#include /* 使用BSD socket,需要包含sockets.h头文件 */ +#include "netdb.h" const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* 发送用到的数据 */ void udpclient(const char* url, int port, int count) @@ -40,7 +42,7 @@ void udpclient(const char* url, int port, int count) } /* 关闭这个socket */ - lwip_close(sock); + closesocket(sock); } #ifdef RT_USING_FINSH diff --git a/examples/network/udpserver.c b/examples/network/udpserver.c index cacd93b8393a0bd91517511dc6d2959eea9789c9..3b5abd976bd91ebde53c3ecf57b9e90dcb261020 100644 --- a/examples/network/udpserver.c +++ b/examples/network/udpserver.c @@ -1,5 +1,8 @@ #include -#include /* 使用BSD socket,需要包含sockets.h头文件 */ +//#include /* 使用BSD socket,需要包含sockets.h头文件 */ +#include /* 使用BSD socket,需要包含sockets.h头文件 */ +#include "netdb.h" + #define BUFSZ 1024 @@ -68,7 +71,7 @@ void udpserv(void* paramemter) /* 如果接收数据是exit,退出 */ if (strcmp(recv_data, "exit") == 0) { - lwip_close(sock); + closesocket(sock); /* 释放接收用的数据缓冲 */ rt_free(recv_data);