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

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

[复制链接]
murphyzhao 发布时间:2019-6-27 09:26
本帖最后由 murphyzhao 于 2019-6-28 08:53 编辑 7 B, W" ~* _8 `8 k
; v2 k/ E. U; x* ~/ J3 Q# {; s1 w
现在都 lwip 210 版本了,无奈,因为客户 SDK 的原因还在捣鼓 lwip151 版本。) M/ _6 }, s* q6 I% R+ x
) B3 p  E: v; U  A
将客户 SDK 升级到 RT-Thread 系统的时候,发现低功耗部分与 LWIP 有耦合,不能直接使用 RT-Thread 移植的 LWIP 组件,也就意味着,我不同享受 RT-Thread netdev 组件和 SAL 组件开发的便利。" x+ [5 D2 P0 l" }" ~0 A8 H9 \# r
$ |: Z" E, a/ [' R, y; g
于是,给自己挖了个坑,把 LWIP151 版本对接到 netdev 和 sal 组件上
' [0 C5 C( w5 _# J" Z
* h$ J. C4 i& V2 ^为了测试,捣鼓了一个简单的 TCP 客户端程序,后面有时间也把对接 RT-Thread netdev 组件和 SAL 组件的过程也给分享出来。
4 z; `. k1 u* Z! J
' f0 N0 ^* V$ P( P# m$ C0 V4 @这里提供的代码基于 BSD-type 风格的 socket 函数接口,你可以在任何支持 BSD socket 的平台上使用这段程序,当然这段程序也可以在包含了 RT-Thread SAL 的使用方法,引入 SAL 相关头文件。
$ W: E2 k: T' }* u9 N/ w. j9 s9 C$ A- {9 m2 r6 m
  1. #include <stdio.h>$ O) M0 d" h( ~) ^- |# s
  2. #include <string.h>* X" t% g" J6 F* E$ h' e7 r
  3. #include <rtthread.h>) [) G' E# ~8 a# t  J
  4. 7 v# u0 O7 ?- U" w, b# P# B; ?1 M
  5. /* 引入 lwip socket 头文件 */, b* ~+ O3 C2 F* `/ \* e
  6. #include "lwip/sockets.h"
    + g" W0 W; f9 z+ Z6 |% w
  7. #include "lwip/netdb.h"8 N  j+ Y0 r9 ^) D; b9 m# q
  8. #include "lwip/sys.h"
    * W: d1 o+ [7 P9 ~# b
  9. " l* ^* H8 Q; W) c+ A
  10. #define TCP_TEST_HOST    "your host or ip addr" /* 输入你的 TCP server 域名或者 ip 地址 */
    # O, y5 J$ D$ a( L' f6 R9 K
  11. #define TCP_TEST_PORT    (80u)                  /* 输入你的 TCP Server 断口号 */
    ) O: ]6 F! h% W  i. |
  12. #define TEST_BUFSZ       (1024u)1 z9 Z' _; z' Q% w( w3 o& [

  13. - q$ J8 d6 b  I3 m- H; R
  14. static const char *send_tcp_req_data = "Hi, I am from tcp client.";! D+ Z  ^  X( X8 r3 I' q' b
  15. & e0 O7 ~) L6 q7 E1 e! K
  16. static void _tcp_test(void)* `/ P' H7 ?( ~% C2 n" |  p
  17. {
    / h1 s9 ?8 W4 t: _$ {
  18.     int ret, i;* T+ L7 U( [7 j/ X
  19.     char *recv_data;6 E% ?3 I) r; x0 z1 R
  20.     struct hostent *host;
    ; j0 n5 V3 a8 [) K& t! W
  21.     int sock = -1, bytes_received;! K' a3 S! q  n- J
  22.     struct sockaddr_in server_addr;! n5 v- X- y0 _

  23. - U# n5 ~& o# l; ^
  24.     /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
    * ]( ~9 M: I4 \5 C
  25.     host = gethostbyname(TCP_TEST_HOST);/ U# ~" w- S3 x% {& J# q9 X
  26.     if (!host)9 d7 Q) ?% ]0 N+ s0 |( D% p4 \
  27.     {
    3 @, G! z: r  U2 b+ o* k( X$ ~& B2 _
  28.         rt_kprintf("gethostbyname failed!\r\n");( W5 P* U) \+ {3 D
  29.         return;1 x, e. ~' m) w9 X
  30.     }
    - `3 I& j; f) Y
  31.     else
    ) ?+ Z) c4 r* F4 e" Q& L; y
  32.     {
      O1 e9 x( N1 u% W7 K
  33.         rt_kprintf("gethostbyname success!\r\n");. p* A. \/ C* w
  34.     }
    " E- h$ G( l/ N( k) r# j( e4 ^
  35. 4 N; k- S  t  W& r$ H
  36.     recv_data = calloc(1, TEST_BUFSZ);
    ' x7 f6 u1 I/ [. C
  37.     if (recv_data == RT_NULL)) U* y: Z- x0 ^' L4 F
  38.     {
    7 p0 O6 F# Y0 R/ h% o3 P5 L
  39.         rt_kprintf("No memory\n");
    $ _: e9 ~5 |5 ]' P' A
  40.         return;" ^. b! \1 H- |4 a% ~' W# F
  41.     }
    ( z! e1 q1 c$ v) W
  42. & l' r  g* e/ I
  43.     /* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */0 ~! x. C% ?- p
  44.     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)6 Y  m; c0 C- D- f  D  C
  45.     {
    4 E: G3 U0 X- _, _
  46.         rt_kprintf("Socket error\n");
    & Q3 i3 r+ W- B9 G, q( I. O2 j
  47.         goto __exit;
    % b, s, Q1 C4 N9 k; l9 |
  48.     }5 Q& S3 R4 R1 P# S7 Y6 v$ v- R
  49.     else
    6 B9 `) o: \- {' a
  50.     {
    4 i& b2 v) ?& m# ~, N# ~
  51.         rt_kprintf("Socket pass\n");
      i) K$ S$ v' T; P7 {
  52.     }  m4 X  O+ M0 ~3 j

  53. 2 A6 J9 z# X) e* F, B1 ~
  54.     /* 初始化预连接的服务端地址 */
    0 p, M& f5 Q1 V9 {
  55.     server_addr.sin_family = AF_INET;
    9 r8 u$ C6 h" D/ J5 d
  56.     server_addr.sin_port = htons(TCP_TEST_PORT);2 N1 Q  \8 l+ C* A
  57.     server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    4 t6 [  N) u; _* {8 k; r
  58.     memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));2 U! \7 _( f  p! q! g. p0 O

  59. * b" ^4 H3 \) l* h& U
  60.     rt_kprintf("will connect...\n");
    " s* y* [  b) b+ a# A) Z: ?, d
  61.     if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0). w. I, e0 p& w( v
  62.     {" c$ J7 \* E  L3 I5 _1 |+ J8 E+ ?& ~
  63.         rt_kprintf("Connect fail!\n");
    3 x' @& J7 E9 R4 `0 P" O; H
  64.         goto __exit;2 l; E0 S- }; F5 E: `# k
  65.     }: E7 w5 _# c  K7 }) X
  66.     else
    , m, H+ H9 K) G' n. \! [7 Y
  67.     {& ]- |% N# N6 W+ }! G6 @( ?' Y
  68.         rt_kprintf("Connect pass!\n");( w# L" \( t9 g! Z5 Y% O4 i2 B
  69.     }' ^! ?8 b# v- t
  70. * D( d3 V0 [% W5 q- V  |* u7 B' Y, g
  71.     /* 发送数据到 socket 连接 */
    ! J" u- p" Z2 _* y3 \+ l4 m
  72.     ret = send(sock, send_tcp_req_data, strlen(send_tcp_req_data), 0);
    $ I4 S  {! R* |! g& T
  73.     if (ret <= 0)( A% N% _# |- U* d( w8 j. x
  74.     {
    # ]+ M; k1 ^2 c$ {" a
  75.         rt_kprintf("send error,close the socket.\n");
    # x/ d- K( t1 G( w3 W
  76.         goto __exit;0 e( y! B0 f9 {; c! C. a% ]! I0 s
  77.     }1 @& X+ ~* ?5 H1 p* Z' Z! b8 V# X7 E
  78.     else  N; j( E9 }. `4 V- K% m) q, s
  79.     {4 `0 l9 Y" w5 @' K# |
  80.         rt_kprintf("send pass!\n");* W- ?0 Z- [' @$ d/ L1 o
  81.     }5 j  E0 F- c5 h9 |5 s/ d3 }- c
  82. 2 {% D6 F+ O( Y  A
  83.     /* 接收并打印响应的数据,使用加密数据传输 */
    5 L& z" k: L0 j/ Y9 u2 _9 o
  84.     bytes_received = recv(sock, recv_data, TEST_BUFSZ - 1, 0);
      l1 |! i- |6 B! R4 E# ]
  85.     if (bytes_received <= 0)
    % {1 M% W" r& |- W) C
  86.     {
    ) s  M  {, c- C+ K9 h- V' C$ }' A
  87.         rt_kprintf("received error,close the socket.\n");% M# ~0 x6 k& K7 D
  88.         goto __exit;% J5 T! P: M0 I& U2 ^) K  e0 p
  89.     }
    ) P: P* H2 D9 @; B' c- w! a
  90. 1 U7 d% q1 }; b; L, G0 J1 l
  91.     rt_kprintf("recv data:\n");
    ' }! b) k/ w% @& t1 H
  92.     for (i = 0; i < bytes_received; i++)
    6 c, V; u0 u& m  Z) d4 n0 @
  93.     {( r  \, L8 l; M, C( Z/ P6 k
  94.         rt_kprintf("%c", recv_data);
    6 X! R" }5 z8 e, Q4 Y; X! _
  95.     }
    6 k& t( Z3 r# {  z0 E

  96. * o$ [2 G$ P( F2 ~( e9 a' l
  97. __exit:. a* ~' S# Z7 {
  98.     if (recv_data)
    " {4 y2 a4 h$ l# u, _4 K
  99.         rt_free(recv_data);
    ; D2 |5 V% Y! A  g$ z" ]# z7 R! G
  100. . l% x) p) A+ ^5 u/ Y5 k3 X1 B: H7 ~
  101.     if (sock >= 0)
    ' G0 V1 ]# _) t  h7 C8 |+ h6 N0 S" Q
  102.         close(sock);
    ( J/ A+ F9 \, Y1 @& Y
  103. }
    * C: H% p2 V; r) i9 \/ K& E
  104. ( ^7 P% N: d6 s) v
  105. void tcp_test(void)
    5 R5 j3 ^  ?+ k9 c* s
  106. {
    3 I& P0 d4 n9 [& q
  107.     rt_thread_t tid;
    ; k9 q! t! x) j8 j9 \# P) s
  108.     tid = rt_thread_create("tcp", _tcp_test, NULL, 4096, 23, 5);3 _# L0 R" O3 T" |
  109.     if (tid), ]! T5 s* j8 u4 n
  110.         rt_thread_startup(tid);3 b( m0 g4 v4 ~; O5 A; U* }- i
  111.     else
    7 ~& x6 S% r# S. A% i) H) I
  112.     {
    4 V  ?# e# ]1 c. q5 j
  113.         rt_kprintf("tcp thread create failed!\r\n");
    2 T( t2 A$ r/ t0 w( B) A& |' Z& I! J
  114.     }
    8 z" k) K- Q$ Z- @! M) a
  115. }
    7 y. u' T" i; Y3 i  n

  116. 4 j- c: e8 \) ]4 A  U) N+ p
  117. #ifdef FINSH_USING_MSH
    9 v% A. T3 B1 l
  118. #include <finsh.h>. n1 r3 w* X) T( d% l6 K# i
  119. MSH_CMD_EXPORT(tcp_test, TCP function test);
    4 n- U0 d, M0 |9 v
  120. #endif /* FINSH_USING_MSH */* M' m. W: q5 j. O9 S
复制代码
. N& y# x8 F; t- D7 f7 ^% m8 Y
, v+ k9 v3 J; [/ G  Z. x# Z) ^. t
如果你也是使用 RT-Thread,那么直接复制代码加入编译,然后在 MSH 中运行既可以:' T9 O# B) ^: R0 S+ H/ X, H& l4 W

7 h+ r! I" q; s  ^
  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
之前粘贴的代码有问题,这下学会怎么插入代码了。6 J7 f: y1 W- r% I
- ]0 \+ B. |! I! P* Q
从文本编辑器复制代码,粘贴到论坛里的代码插入标签,提交之后会插入到当前光标位置。
- h: A& [( F- m0 K' w7 A这个时候你看到的代码格式是乱掉的,没有空格缩进等,不要紧,保存提交帖子即可,这个时候会发现,代码格式显示正常了。

所属标签

相似分享

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