Skip to content

Commit 1b351ff

Browse files
authored
Merge pull request #1947 from zhaojuntao/update-examples
[examples][network] 更新 tcp/udp client & server 例程
2 parents 2d4704b + e9c795e commit 1b351ff

File tree

4 files changed

+608
-165
lines changed

4 files changed

+608
-165
lines changed

examples/network/tcpclient.c

Lines changed: 161 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,69 @@
11
#include <rtthread.h>
2+
#include <string.h>
23

4+
#if !defined(SAL_USING_POSIX)
5+
#error "Please enable SAL_USING_POSIX!"
6+
#else
7+
#include <sys/time.h>
8+
#include <sys/select.h>
9+
#endif
310
#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
411
#include "netdb.h"
512

13+
#define DEBUG_TCP_CLIENT
14+
15+
#define DBG_ENABLE
16+
#define DBG_SECTION_NAME "TCP"
17+
#ifdef DEBUG_TCP_CLIENT
18+
#define DBG_LEVEL DBG_LOG
19+
#else
20+
#define DBG_LEVEL DBG_INFO /* DBG_ERROR */
21+
#endif
22+
#define DBG_COLOR
23+
#include <rtdbg.h>
24+
625
#define BUFSZ 1024
726

27+
static int started = 0;
28+
static int is_running = 0;
29+
static char url[256];
30+
static int port = 8080;
831
static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */
9-
void tcpclient(const char *url, int port)
32+
33+
static void tcpclient(void *arg)
1034
{
1135
int ret;
1236
char *recv_data;
13-
struct hostent *host;
14-
int sock, bytes_received;
37+
int bytes_received;
38+
int sock = -1;
39+
struct hostent *host = RT_NULL;
1540
struct sockaddr_in server_addr;
1641

42+
struct timeval timeout;
43+
fd_set readset;
44+
1745
/* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
1846
host = gethostbyname(url);
47+
if (host == RT_NULL)
48+
{
49+
LOG_E("Get host by name failed!");
50+
return;
51+
}
1952

2053
/* 分配用于存放接收数据的缓冲 */
2154
recv_data = rt_malloc(BUFSZ);
2255
if (recv_data == RT_NULL)
2356
{
24-
rt_kprintf("No memory\n");
57+
LOG_E("No memory");
2558
return;
2659
}
2760

2861
/* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */
2962
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
3063
{
3164
/* 创建socket失败 */
32-
rt_kprintf("Socket error\n");
33-
34-
/* 释放接收缓冲 */
35-
rt_free(recv_data);
36-
return;
65+
LOG_E("Create socket error");
66+
goto __exit;
3767
}
3868

3969
/* 初始化预连接的服务端地址 */
@@ -46,78 +76,159 @@ void tcpclient(const char *url, int port)
4676
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
4777
{
4878
/* 连接失败 */
49-
rt_kprintf("Connect fail!\n");
50-
closesocket(sock);
51-
52-
/*释放接收缓冲 */
53-
rt_free(recv_data);
54-
return;
79+
LOG_E("Connect fail!");
80+
goto __exit;
5581
}
5682

57-
while (1)
83+
started = 1;
84+
is_running = 1;
85+
86+
timeout.tv_sec = 3;
87+
timeout.tv_usec = 0;
88+
89+
while (is_running)
5890
{
91+
FD_ZERO(&readset);
92+
FD_SET(sock, &readset);
93+
94+
/* Wait for read */
95+
if (select(sock + 1, &readset, RT_NULL, RT_NULL, &timeout) == 0)
96+
continue;
97+
5998
/* 从sock连接中接收最大BUFSZ - 1字节数据 */
6099
bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
61100
if (bytes_received < 0)
62101
{
63102
/* 接收失败,关闭这个连接 */
64-
closesocket(sock);
65-
rt_kprintf("\nreceived error,close the socket.\r\n");
66-
67-
/* 释放接收缓冲 */
68-
rt_free(recv_data);
69-
break;
103+
LOG_E("Received error, close the socket.");
104+
goto __exit;
70105
}
71106
else if (bytes_received == 0)
72107
{
73108
/* 打印recv函数返回值为0的警告信息 */
74-
rt_kprintf("\nReceived warning,recv function return 0.\r\n");
75-
109+
LOG_W("Received warning, recv function return 0.");
76110
continue;
77111
}
78-
79-
/* 有接收到数据,把末端清零 */
80-
recv_data[bytes_received] = '\0';
81-
82-
if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0)
83-
{
84-
/* 如果是首字母是q或Q,关闭这个连接 */
85-
closesocket(sock);
86-
rt_kprintf("\n got a 'q' or 'Q',close the socket.\r\n");
87-
88-
/* 释放接收缓冲 */
89-
rt_free(recv_data);
90-
break;
91-
}
92112
else
93113
{
94-
/* 在控制终端显示收到的数据 */
95-
rt_kprintf("\nReceived data = %s ", recv_data);
114+
/* 有接收到数据,把末端清零 */
115+
recv_data[bytes_received] = '\0';
116+
117+
if (rt_strcmp(recv_data, "q") == 0 || rt_strcmp(recv_data, "Q") == 0)
118+
{
119+
/* 如果是首字母是q或Q,关闭这个连接 */
120+
LOG_I("Got a 'q' or 'Q', close the socket.");
121+
goto __exit;
122+
}
123+
else
124+
{
125+
/* 在控制终端显示收到的数据 */
126+
LOG_D("Received data = %s", recv_data);
127+
}
96128
}
97129

98130
/* 发送数据到sock连接 */
99-
ret = send(sock, send_data, strlen(send_data), 0);
131+
ret = send(sock, send_data, rt_strlen(send_data), 0);
100132
if (ret < 0)
101133
{
102134
/* 接收失败,关闭这个连接 */
103-
closesocket(sock);
104-
rt_kprintf("\nsend error,close the socket.\r\n");
105-
106-
rt_free(recv_data);
107-
break;
135+
LOG_I("send error, close the socket.");
136+
goto __exit;
108137
}
109138
else if (ret == 0)
110139
{
111140
/* 打印send函数返回值为0的警告信息 */
112-
rt_kprintf("\n Send warning,send function return 0.\r\n");
141+
LOG_W("Send warning, send function return 0.");
142+
}
143+
}
144+
145+
__exit:
146+
if (recv_data)
147+
{
148+
rt_free(recv_data);
149+
recv_data = RT_NULL;
150+
}
151+
if (sock >= 0)
152+
{
153+
closesocket(sock);
154+
sock = -1;
155+
}
156+
started = 0;
157+
is_running = 0;
158+
return;
159+
}
160+
161+
static void usage(void)
162+
{
163+
rt_kprintf("Usage: tcpclient -h <host> -p <port>\n");
164+
rt_kprintf(" tcpclient --stop\n");
165+
rt_kprintf(" tcpclient --help\n");
166+
rt_kprintf("\n");
167+
rt_kprintf("Miscellaneous:\n");
168+
rt_kprintf(" -h Specify host address\n");
169+
rt_kprintf(" -p Specify the host port number\n");
170+
rt_kprintf(" --stop Stop tcpclient program\n");
171+
rt_kprintf(" --help Print help information\n");
172+
}
173+
174+
static void tcpclient_test(int argc, char** argv)
175+
{
176+
rt_thread_t tid;
177+
178+
if (argc == 1 || argc > 5)
179+
{
180+
LOG_I("Please check the command you entered!\n");
181+
goto __usage;
182+
}
183+
else
184+
{
185+
if (rt_strcmp(argv[1], "--help") == 0)
186+
{
187+
goto __usage;
188+
}
189+
else if (rt_strcmp(argv[1], "--stop") == 0)
190+
{
191+
is_running = 0;
192+
return;
193+
}
194+
else if (rt_strcmp(argv[1], "-h") == 0 && rt_strcmp(argv[3], "-p") == 0)
195+
{
196+
if (started)
197+
{
198+
LOG_I("The tcpclient has started!");
199+
LOG_I("Please stop tcpclient firstly, by: tcpclient --stop");
200+
return;
201+
}
202+
203+
if (rt_strlen(argv[2]) > sizeof(url))
204+
{
205+
LOG_E("The input url is too long, max %d bytes!", sizeof(url));
206+
return;
207+
}
208+
rt_memset(url, 0x0, sizeof(url));
209+
rt_strncpy(url, argv[2], rt_strlen(argv[2]));
210+
port = atoi(argv[4]);
211+
}
212+
else
213+
{
214+
goto __usage;
113215
}
114216
}
115217

218+
tid = rt_thread_create("tcp_client",
219+
tcpclient, RT_NULL,
220+
2048, RT_THREAD_PRIORITY_MAX/3, 20);
221+
if (tid != RT_NULL)
222+
{
223+
rt_thread_startup(tid);
224+
}
116225
return;
226+
227+
__usage:
228+
usage();
117229
}
118230

119231
#ifdef RT_USING_FINSH
120-
#include <finsh.h>
121-
/* 输出tcpclient函数到finsh shell中 */
122-
FINSH_FUNCTION_EXPORT(tcpclient, startup tcp client);
232+
MSH_CMD_EXPORT_ALIAS(tcpclient_test, tcpclient,
233+
Start a tcp client. Help: tcpclient --help);
123234
#endif

0 commit comments

Comments
 (0)