你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

一个简单的 TCP 客户端测试程序

[复制链接]
murphyzhao 发布时间:2019-6-27 09:26
本帖最后由 murphyzhao 于 2019-6-28 08:53 编辑
7 D4 U% Y7 v$ K* a9 K5 Y( x/ |+ s. ?4 F; E' T: y
现在都 lwip 210 版本了,无奈,因为客户 SDK 的原因还在捣鼓 lwip151 版本。
& w1 [, X5 b/ J/ M& u8 Y8 R! i+ U) ^$ X. q6 V, [$ t8 x
将客户 SDK 升级到 RT-Thread 系统的时候,发现低功耗部分与 LWIP 有耦合,不能直接使用 RT-Thread 移植的 LWIP 组件,也就意味着,我不同享受 RT-Thread netdev 组件和 SAL 组件开发的便利。
2 o$ @& P0 J7 c9 u0 v9 v, F4 M" @6 B' m( J/ {+ ~
于是,给自己挖了个坑,把 LWIP151 版本对接到 netdev 和 sal 组件上
4 I  q5 ]' _! h# `/ v# B/ U) `
8 Q& ~# k! R+ r( p3 h1 \8 V& D为了测试,捣鼓了一个简单的 TCP 客户端程序,后面有时间也把对接 RT-Thread netdev 组件和 SAL 组件的过程也给分享出来。" m8 R3 ^6 Z/ h# O4 J2 v7 G, H- o

1 U2 n+ U4 G4 q" ?# _这里提供的代码基于 BSD-type 风格的 socket 函数接口,你可以在任何支持 BSD socket 的平台上使用这段程序,当然这段程序也可以在包含了 RT-Thread SAL 的使用方法,引入 SAL 相关头文件。
! e) \* n7 s- f# E  y! ^0 J* [4 x3 F7 l: m0 N1 ?* Y1 c) x. T9 q
  1. #include <stdio.h>
    1 I7 w" x+ v& M3 y0 a/ R) y4 p
  2. #include <string.h>
    2 Q7 E" L) S2 w" R  ]
  3. #include <rtthread.h>9 H8 [# n% j* e. k4 z5 f  G9 d7 W
  4. ! D; H; J, W: u3 d+ e
  5. /* 引入 lwip socket 头文件 */' I4 J( O6 L4 z+ L, W# b5 v
  6. #include "lwip/sockets.h"
    + K8 N* m3 j  B0 b  ^1 ~- T( t$ p8 W
  7. #include "lwip/netdb.h"
    ) Y3 T* q9 ~2 n7 _
  8. #include "lwip/sys.h"  m" k9 M! v3 M7 T

  9. / s. |( n- q2 m7 Y
  10. #define TCP_TEST_HOST    "your host or ip addr" /* 输入你的 TCP server 域名或者 ip 地址 */
    - k% h4 Z. D; o# [6 r0 P) e
  11. #define TCP_TEST_PORT    (80u)                  /* 输入你的 TCP Server 断口号 */0 g9 B! n% B9 ?& L! a+ Y# z7 C
  12. #define TEST_BUFSZ       (1024u)
    ) L, }* c% h! C$ l6 \( D3 f
  13. . G( }" `' f4 S7 g- I
  14. static const char *send_tcp_req_data = "Hi, I am from tcp client.";
    - z/ y- z; `3 a0 g4 ^' w

  15. 0 `) T6 @, n$ `$ J) R; U& G1 x! g
  16. static void _tcp_test(void)0 m. k4 a3 Q4 l* G8 E
  17. {
    & ?/ M2 {& I  c3 ]4 l
  18.     int ret, i;
    4 e+ |) y5 Y7 t2 O2 U
  19.     char *recv_data;
    3 n8 ?# N. _6 \$ v1 n1 p
  20.     struct hostent *host;: G! r3 t" N5 c, h3 k
  21.     int sock = -1, bytes_received;
    ; N& r3 T: f1 t, Z" t9 q0 R) P/ ?
  22.     struct sockaddr_in server_addr;7 i$ f- d, `& [, w6 F/ Y

  23. 7 I6 z. h3 ?5 r" f
  24.     /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */) U; x4 B# z% {5 `3 r
  25.     host = gethostbyname(TCP_TEST_HOST);) \" h$ T7 y: V5 l- ^* e; p( b
  26.     if (!host)) X' h2 f$ p% {$ b) |' ?5 @
  27.     {
    ! Y. o, y1 n: K8 A8 M: G6 g
  28.         rt_kprintf("gethostbyname failed!\r\n");  K; R6 l- p# l0 E
  29.         return;
    5 {  r. y0 b4 x
  30.     }+ ^& R. |9 G* M' y+ p% a% n
  31.     else
    9 b8 X8 b) g9 m4 Z
  32.     {; B3 J4 J- U; l5 L* n9 j
  33.         rt_kprintf("gethostbyname success!\r\n");
    5 ^% |/ T" [: |; V# c6 i7 i
  34.     }
    * n% y  A* I4 Q( v1 J4 G0 I! O& a

  35. + h0 V9 X+ |) ]  r. c
  36.     recv_data = calloc(1, TEST_BUFSZ);5 z# A6 x( V& [2 E
  37.     if (recv_data == RT_NULL)0 I% I8 N& D2 u  S2 @$ P5 U8 b
  38.     {
    - @& M- H$ \0 j3 {
  39.         rt_kprintf("No memory\n");6 t( N" f) ?" G& s. Q& F' G2 ^
  40.         return;
    ; ]  _' q. X. s) b: H8 y" R1 \% T
  41.     }
    - h3 a5 |; J$ f$ l" [( h) s
  42. % R* J9 P4 F( a% `
  43.     /* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */1 {  Z. P0 j, q+ N# G- h9 j
  44.     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)1 @- d9 S/ l* L* m8 T, i1 h
  45.     {* d0 {0 v# m2 H5 W, R( v" [+ d! m
  46.         rt_kprintf("Socket error\n");
    ! p/ m: f. m+ `
  47.         goto __exit;9 \7 C$ W$ V9 _, w! b+ E, _
  48.     }8 B& Q2 \3 V: d1 G; o+ I0 R& s
  49.     else
    3 p' P" A. r& o+ F' `2 F' u6 Z) a& ~
  50.     {+ |  v9 A+ G1 [4 {& o/ G
  51.         rt_kprintf("Socket pass\n");# b$ J$ _: J! X; J" O: ?
  52.     }( G! h6 v9 m  ^
  53. / `7 i- z9 j1 b7 \9 y# E
  54.     /* 初始化预连接的服务端地址 */$ V# d* T. f3 ~" a. g
  55.     server_addr.sin_family = AF_INET;, v4 C$ P. I4 ^
  56.     server_addr.sin_port = htons(TCP_TEST_PORT);0 t: @! a/ N# V# ?. B/ \  C
  57.     server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    ! x2 b$ w5 k) w
  58.     memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));4 i3 Y. h" H/ t6 D7 \% {( e

  59. 8 y9 U/ p, M0 b2 @8 c/ [  s
  60.     rt_kprintf("will connect...\n");  x4 M4 L3 _9 J* v8 L( _
  61.     if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
    4 `3 ^2 a+ j( Z0 {( H5 f4 R* j
  62.     {
    9 a/ R; U' r0 V0 ~& K4 t' Q: F
  63.         rt_kprintf("Connect fail!\n");# r4 B, P; g; U1 T, V0 v2 U. H4 |
  64.         goto __exit;' k% a; Y$ H3 @
  65.     }2 R& s9 ]7 M) l/ k; r" ]$ W# N
  66.     else
    9 z* t0 L0 b8 R3 q
  67.     {
    , ]4 t. q  H' p9 t. s
  68.         rt_kprintf("Connect pass!\n");2 [+ n: O2 _, |: o5 L
  69.     }
    ( o7 i- p4 [8 h) P
  70. 5 g6 b- D; D7 V: ?% }) E! |
  71.     /* 发送数据到 socket 连接 */
    7 w4 B3 S& y2 ~0 O8 T2 Y9 d
  72.     ret = send(sock, send_tcp_req_data, strlen(send_tcp_req_data), 0);
    # F+ k$ g( \9 R+ f2 ~
  73.     if (ret <= 0)& ?% W$ Q8 I! f: t) D
  74.     {, }- |  }2 c  d, O+ M3 \- B
  75.         rt_kprintf("send error,close the socket.\n");  A8 }8 E) `& e7 [+ R- H
  76.         goto __exit;' ~. z5 V. D# H
  77.     }
    0 V  H5 n1 W2 o7 V8 U; @2 u
  78.     else
    9 S! E) f, I. r4 f+ q# q
  79.     {  h( O. ~8 c" i  a
  80.         rt_kprintf("send pass!\n");
    ) ?8 f7 Z: `  x  D8 |* _
  81.     }
    0 A( d: r- H8 g' i' r

  82. ! i& G3 f8 T% j4 T, [% v* ~
  83.     /* 接收并打印响应的数据,使用加密数据传输 */, |6 c1 C8 t& U4 ~
  84.     bytes_received = recv(sock, recv_data, TEST_BUFSZ - 1, 0);
      K) M/ \5 o; j" w& i( a$ V; ^
  85.     if (bytes_received <= 0)
    ( ~8 Z, `* h- N+ k% _& W: L
  86.     {9 @" Y0 A6 U) C$ Y' W& y& C
  87.         rt_kprintf("received error,close the socket.\n");/ o' _4 d; j, ?& i, l" ^! U
  88.         goto __exit;) G2 n- ~! d+ I& E
  89.     }
    , v; T4 |1 T4 J0 T, c( E( d2 m$ F* I

  90. / Q4 I( g  n' \( v2 X
  91.     rt_kprintf("recv data:\n");5 e+ a/ s& H' U+ j& e+ D
  92.     for (i = 0; i < bytes_received; i++)6 b+ F' R: U) t8 d" X: s* J
  93.     {
    $ u/ R$ D' y, o' ^3 {5 l, R4 X
  94.         rt_kprintf("%c", recv_data);+ N0 g8 [) y+ c* @
  95.     }9 H! l/ U# |3 |/ ~, P

  96. " p" ~) n* c/ O# Q1 c1 w5 n
  97. __exit:# J' D( x- ]$ u$ C' b2 H: J
  98.     if (recv_data)
      C* S; |; c& A( k3 G8 n
  99.         rt_free(recv_data);
    ' X% {4 n3 }. t) w, Z  d1 ]8 f& E
  100. 2 L2 _: ]7 E  R1 [8 Q! S  j
  101.     if (sock >= 0)
    & ^! U' l' B7 P) n- \
  102.         close(sock);3 @; X" d4 o6 T6 Z8 Y+ h* X
  103. }
    6 i7 ?6 ?. s4 Z) M6 V

  104. , t$ ?. h, n4 b0 a; Y% y2 w, @
  105. void tcp_test(void)! p$ _# D( s+ S1 a- [9 K
  106. {1 }( b; m7 U' v, U" l
  107.     rt_thread_t tid;  f/ R  r! i' y
  108.     tid = rt_thread_create("tcp", _tcp_test, NULL, 4096, 23, 5);. H6 ?7 ^0 m/ e! H. i4 C
  109.     if (tid)$ q2 n1 P4 g1 l9 i
  110.         rt_thread_startup(tid);
    3 v% X2 T: x& B1 q
  111.     else4 Q' l& K$ w/ o9 t: m$ _
  112.     {
    5 x% p( _5 u, J( C* ]' ^
  113.         rt_kprintf("tcp thread create failed!\r\n");
    3 [5 e( r/ ^% V/ |' b4 y% y
  114.     }
    ! G2 R. ?0 ?- r: m* O# t( ]& c1 u0 j% U
  115. }
    4 W  e3 k4 m6 R/ z" P) @

  116. 6 w. g$ n7 C; M% x
  117. #ifdef FINSH_USING_MSH% n* M& ?* r% x9 V
  118. #include <finsh.h>" E  b- ^  i8 x) U6 z% K: `
  119. MSH_CMD_EXPORT(tcp_test, TCP function test);, @5 Z* e2 {$ q6 y4 d
  120. #endif /* FINSH_USING_MSH */
    0 u7 r1 I4 l9 a; Y
复制代码

' x. c6 w; J5 A, O" e( A0 b" S0 a, T8 g
如果你也是使用 RT-Thread,那么直接复制代码加入编译,然后在 MSH 中运行既可以:8 g- `/ q7 X' g$ J$ f2 y( {/ E/ O

2 C" ]' ]8 x0 j1 |# j8 c
  1. msh /> tcp_test
复制代码
tcp_client.rar (1.32 KB, 下载次数: 3)
收藏 评论1 发布时间:2019-6-27 09:26

举报

1个回答
murphyzhao 回答时间:2019-6-28 08:56:29
之前粘贴的代码有问题,这下学会怎么插入代码了。
* |) J/ F2 u9 D* n; |
  `' q# F  A7 @' V# [% p4 o从文本编辑器复制代码,粘贴到论坛里的代码插入标签,提交之后会插入到当前光标位置。# l# x$ @. X' B( k5 a
这个时候你看到的代码格式是乱掉的,没有空格缩进等,不要紧,保存提交帖子即可,这个时候会发现,代码格式显示正常了。

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版