lwIP socket 编程:TCP client 示例程序
每一次调试网络相关的代码都需要一段最简单的 socket 测试程序,后来就写了个简单的 TCP 客户端程序,并把这个程序记录到了代码片段,方便后面引用,避免重复工作浪费时间。
简单的 TCP 客户端程序源码
因为本人使用的是 RT-Thread RTOS 平台,所有下面的代码也是基于 RT-Thread OS 下测试使用,并验证通过。当然,socket 编程是标准的,这里提供的代码基于 BSD-type 风格的 socket 函数接口,你可以在任何支持 BSD socket 的平台上使用这段程序。
源码如下所示:
#include <stdio.h>
#include <string.h>
#include <rtthread.h>
#include "lwip/sockets.h"
#include "lwip/netdb.h"
#include "lwip/sys.h"
#define TCP_TEST_HOST "your host or ip addr" /* 输入你的 TCP server 域名或者 ip 地址 */
#define TCP_TEST_PORT (80u) /* 输入你的 TCP Server 断口号 */
#define TEST_BUFSZ (1024u)
static const char *send_tcp_req_data = "Hi, I am from tcp client.";
static void _tcp_test(void)
{
int ret, i;
char *recv_data;
struct hostent *host;
int sock = -1, bytes_received;
struct sockaddr_in server_addr;
/* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
host = gethostbyname(TCP_TEST_HOST);
if (!host)
{
rt_kprintf("gethostbyname failed!\r\n");
return;
}
else
{
rt_kprintf("gethostbyname success!\r\n");
}
recv_data = calloc(1, TEST_BUFSZ);
if (recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return;
}
/* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
rt_kprintf("Socket error\n");
goto __exit;
}
else
{
rt_kprintf("Socket pass\n");
}
/* 初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(TCP_TEST_PORT);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
rt_kprintf("will connect...\n");
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
{
rt_kprintf("Connect fail!\n");
goto __exit;
}
else
{
rt_kprintf("Connect pass!\n");
}
/* 发送数据到 socket 连接 */
ret = send(sock, send_tcp_req_data, strlen(send_tcp_req_data), 0);
if (ret <= 0)
{
rt_kprintf("send error,close the socket.\n");
goto __exit;
}
else
{
rt_kprintf("send pass!\n");
}
/* 接收并打印响应的数据,使用加密数据传输 */
bytes_received = recv(sock, recv_data, TEST_BUFSZ - 1, 0);
if (bytes_received <= 0)
{
rt_kprintf("received error,close the socket.\n");
goto __exit;
}
rt_kprintf("recv data:\n");
for (i = 0; i < bytes_received; i++)
{
rt_kprintf("%c", recv_data);
}
__exit:
if (recv_data)
rt_free(recv_data);
if (sock >= 0)
close(sock);
}
static void tcp_test(void)
{
rt_thread_t tid;
tid = rt_thread_create("tcp", _tcp_test, NULL, 4096, 23, 5);
if (tid)
rt_thread_startup(tid);
else
{
rt_kprintf("tcp thread create failed!\r\n");
}
}
#ifdef FINSH_USING_MSH
#include <finsh.h>
MSH_CMD_EXPORT(tcp_test, TCP function test);
#endif /* FINSH_USING_MSH */
在 RT-Thread MSH 中可以直接使用 Finsh 命令运行:
如果你不是基于 RT-Thread 系统,那么把 RT-Thread 的特性移除掉即可(如 Finsh 运行程序特性)。
这里代码展示不是特别好,附件里有完整的 C 文件。
tcp_client.rar
(1.32 KB)
|