lwIP socket 编程 TCP 客户端程序

[复制链接]
 楼主| 风信子1314 发表于 2019-6-25 08:56 | 显示全部楼层 |阅读模式
lwIP socket 编程:TCP client 示例程序

每一次调试网络相关的代码都需要一段最简单的 socket 测试程序,后来就写了个简单的 TCP 客户端程序,并把这个程序记录到了代码片段,方便后面引用,避免重复工作浪费时间。

简单的 TCP 客户端程序源码
因为本人使用的是 RT-Thread RTOS 平台,所有下面的代码也是基于 RT-Thread OS 下测试使用,并验证通过。当然,socket 编程是标准的,这里提供的代码基于 BSD-type 风格的 socket 函数接口,你可以在任何支持 BSD socket 的平台上使用这段程序。

源码如下所示:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <rtthread.h>

  4. #include "lwip/sockets.h"
  5. #include "lwip/netdb.h"
  6. #include "lwip/sys.h"

  7. #define TCP_TEST_HOST    "your host or ip addr"  /* 输入你的 TCP server 域名或者 ip 地址 */
  8. #define TCP_TEST_PORT    (80u)                   /* 输入你的 TCP Server 断口号 */
  9. #define TEST_BUFSZ       (1024u)

  10. static const char *send_tcp_req_data = "Hi, I am from tcp client.";

  11. static void _tcp_test(void)
  12. {
  13.     int ret, i;
  14.     char *recv_data;
  15.     struct hostent *host;
  16.     int sock = -1, bytes_received;
  17.     struct sockaddr_in server_addr;

  18.     /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
  19.     host = gethostbyname(TCP_TEST_HOST);
  20.     if (!host)
  21.     {
  22.         rt_kprintf("gethostbyname failed!\r\n");
  23.         return;
  24.     }
  25.     else
  26.     {
  27.         rt_kprintf("gethostbyname success!\r\n");
  28.     }

  29.     recv_data = calloc(1, TEST_BUFSZ);
  30.     if (recv_data == RT_NULL)
  31.     {
  32.         rt_kprintf("No memory\n");
  33.         return;
  34.     }

  35.     /* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */
  36.     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  37.     {
  38.         rt_kprintf("Socket error\n");
  39.         goto __exit;
  40.     }
  41.     else
  42.     {
  43.         rt_kprintf("Socket pass\n");
  44.     }

  45.     /* 初始化预连接的服务端地址 */
  46.     server_addr.sin_family = AF_INET;
  47.     server_addr.sin_port = htons(TCP_TEST_PORT);
  48.     server_addr.sin_addr = *((struct in_addr *)host->h_addr);
  49.     memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

  50.     rt_kprintf("will connect...\n");
  51.     if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
  52.     {
  53.         rt_kprintf("Connect fail!\n");
  54.         goto __exit;
  55.     }
  56.     else
  57.     {
  58.         rt_kprintf("Connect pass!\n");
  59.     }
  60.     /* 发送数据到 socket 连接 */
  61.     ret = send(sock, send_tcp_req_data, strlen(send_tcp_req_data), 0);
  62.     if (ret <= 0)
  63.     {
  64.         rt_kprintf("send error,close the socket.\n");
  65.         goto __exit;
  66.     }
  67.     else
  68.     {
  69.         rt_kprintf("send pass!\n");
  70.     }

  71.     /* 接收并打印响应的数据,使用加密数据传输 */
  72.     bytes_received = recv(sock, recv_data, TEST_BUFSZ  - 1, 0);
  73.     if (bytes_received <= 0)
  74.     {
  75.         rt_kprintf("received error,close the socket.\n");
  76.         goto __exit;
  77.     }

  78.     rt_kprintf("recv data:\n");
  79.     for (i = 0; i < bytes_received; i++)
  80.     {
  81.         rt_kprintf("%c", recv_data);
  82.     }

  83. __exit:
  84.     if (recv_data)
  85.         rt_free(recv_data);

  86.     if (sock >= 0)
  87.         close(sock);
  88. }

  89. static void tcp_test(void)
  90. {
  91.     rt_thread_t tid;
  92.     tid = rt_thread_create("tcp", _tcp_test, NULL, 4096, 23, 5);
  93.     if (tid)
  94.         rt_thread_startup(tid);
  95.     else
  96.     {
  97.         rt_kprintf("tcp thread create failed!\r\n");
  98.     }
  99. }

  100. #ifdef FINSH_USING_MSH
  101. #include <finsh.h>
  102. MSH_CMD_EXPORT(tcp_test, TCP function test);
  103. #endif /* FINSH_USING_MSH */

在 RT-Thread MSH 中可以直接使用 Finsh 命令运行:


  1. msh /> tcp_test


如果你不是基于 RT-Thread 系统,那么把 RT-Thread 的特性移除掉即可(如 Finsh 运行程序特性)。

这里代码展示不是特别好,附件里有完整的 C 文件。




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 风信子1314 发表于 2019-6-25 09:05 | 显示全部楼层
本帖最后由 风信子1314 于 2019-6-25 09:59 编辑

有一个很好的在线工具 carbon,用于生成代码图片,方便以图片的方式展示代码。参考 Carbon https://blog.csdn.net/u012349679/article/details/89787697。
上面的部分代码展示如下:



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:主页:http://murphy.tech 公众号:物联网学前班

7

主题

21

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部