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

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

[复制链接]
murphyzhao 发布时间:2019-6-27 09:26
本帖最后由 murphyzhao 于 2019-6-28 08:53 编辑
) {, o" e% Z2 v* I' \9 ^  ~7 K2 R
现在都 lwip 210 版本了,无奈,因为客户 SDK 的原因还在捣鼓 lwip151 版本。
% q( L" f1 K( r9 k/ V( s% H# q& ?8 L" h/ H$ w& l8 A! u
将客户 SDK 升级到 RT-Thread 系统的时候,发现低功耗部分与 LWIP 有耦合,不能直接使用 RT-Thread 移植的 LWIP 组件,也就意味着,我不同享受 RT-Thread netdev 组件和 SAL 组件开发的便利。9 `9 H, i8 f8 N0 A( H& G- h
- P  a; p9 }. H
于是,给自己挖了个坑,把 LWIP151 版本对接到 netdev 和 sal 组件上
, l' y& j  O( C2 X
: u! I" F8 l2 S3 n5 z为了测试,捣鼓了一个简单的 TCP 客户端程序,后面有时间也把对接 RT-Thread netdev 组件和 SAL 组件的过程也给分享出来。
- t* n( b* w+ I& n7 h; ?4 Q% @; c* v7 T6 _! y' H+ ]" X
这里提供的代码基于 BSD-type 风格的 socket 函数接口,你可以在任何支持 BSD socket 的平台上使用这段程序,当然这段程序也可以在包含了 RT-Thread SAL 的使用方法,引入 SAL 相关头文件。$ }' U7 C9 a# g4 B: @& r: E
) Q" K* Z8 O& _% \" c9 k
  1. #include <stdio.h>
    - T" d1 F" [6 ~* G' D
  2. #include <string.h>
    # f0 o$ k& u6 n9 ~( Y
  3. #include <rtthread.h>
    ; w: f* q2 ], N2 ?) `
  4. 9 V* j% N" |) F( K
  5. /* 引入 lwip socket 头文件 */
    3 j% z/ Y8 Q+ m  e) ~
  6. #include "lwip/sockets.h"- B3 y2 e# |8 F: w& W! S
  7. #include "lwip/netdb.h"1 f8 h' @2 n9 i7 K
  8. #include "lwip/sys.h"
    ) z# D2 I6 ^0 z! T& D/ Y" ?
  9.   N( h  P. d( B" K! U2 C& k
  10. #define TCP_TEST_HOST    "your host or ip addr" /* 输入你的 TCP server 域名或者 ip 地址 */
    + J- o; ^  \7 x( G9 N( ?" l
  11. #define TCP_TEST_PORT    (80u)                  /* 输入你的 TCP Server 断口号 */
    , A$ f% A# s! G( o7 u
  12. #define TEST_BUFSZ       (1024u)
    6 _! l' a3 c* Z6 V. j( w3 M
  13. $ W) I7 x  \- }3 G
  14. static const char *send_tcp_req_data = "Hi, I am from tcp client.";2 b7 A7 r' C; J% C% W! H

  15. - h$ ^4 ^4 U# Q9 |
  16. static void _tcp_test(void)
    + }2 R! Z' v& J. k
  17. {4 i6 A, Y% i; z  o7 D
  18.     int ret, i;
      p2 |4 N0 A' K" z  w
  19.     char *recv_data;" H* |5 t) m$ |0 U' [$ ^/ B. B( t
  20.     struct hostent *host;' I3 B% B. M+ w
  21.     int sock = -1, bytes_received;! {% v, |* ~2 {: R/ }2 n+ h
  22.     struct sockaddr_in server_addr;& S$ W; @- d0 Y
  23. $ a, F& S! S' i, ?5 V3 N* Q
  24.     /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
    % a* y; `" T1 q7 P+ c
  25.     host = gethostbyname(TCP_TEST_HOST);" ^6 d: _/ O2 y, M. O7 G$ R
  26.     if (!host)
    4 Z9 j7 L) T1 P
  27.     {
    ) S* V3 n: p- N; d* I9 ]
  28.         rt_kprintf("gethostbyname failed!\r\n");7 Q$ @1 G( t6 v2 I4 n+ c
  29.         return;. K& A# T. v3 ^- ~% e, r& v
  30.     }5 {  X  }; \' P* }5 w3 n9 n
  31.     else
    3 A, F) n' l. T( x) z
  32.     {- e; f& M  B" A
  33.         rt_kprintf("gethostbyname success!\r\n");( G9 x# P% S1 `; |) A2 s9 n# M! H
  34.     }9 W7 v4 @$ |$ M( p) B0 e, @
  35.   c" k4 X% h6 U' ~. j
  36.     recv_data = calloc(1, TEST_BUFSZ);8 w: ]( s% ?6 P0 }( l, Q+ }
  37.     if (recv_data == RT_NULL)
    ( M4 ~$ z' @% @; y6 ~5 Q
  38.     {$ v+ J9 N, ^$ B: r5 k2 K
  39.         rt_kprintf("No memory\n");# M% k6 J6 f5 t. ^
  40.         return;; G% m, s% W+ k. p
  41.     }: ~* c( H/ l4 z7 x, X' v
  42. 2 e) b+ l& J+ K- t. ~
  43.     /* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */; k$ C, m$ h$ R% @8 h" a1 G# ?0 J. W
  44.     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)  k9 E# c, L) s5 V3 P
  45.     {2 c# v. K, N" }5 p% U. e
  46.         rt_kprintf("Socket error\n");
    & n- z) t# A1 P, X& R, O8 V
  47.         goto __exit;
    7 j  a: u7 N, V' v' S, b
  48.     }
    + O$ u2 q- k% l) o. o" i" U. ?
  49.     else' y% ~9 y- h6 h3 j, ?
  50.     {
      s# k6 R- j: k! L# C; }7 z  B
  51.         rt_kprintf("Socket pass\n");
    2 k! [( d: ^+ `" f5 E* O9 r
  52.     }
    ; ?4 m2 j* k5 c7 K% Z! H5 J

  53. 3 F: q/ M% z( Z5 e$ {/ a
  54.     /* 初始化预连接的服务端地址 */
    8 d! l6 L3 U7 n
  55.     server_addr.sin_family = AF_INET;
    ' j$ Z( H+ V6 H, ~* m
  56.     server_addr.sin_port = htons(TCP_TEST_PORT);! p: o' [, T4 B$ i
  57.     server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    - N& h, V# e6 ?7 V  U- z0 E
  58.     memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
      M! R. X$ T. C- R6 x& `# M$ i9 o
  59. 5 I6 \. m+ c9 t, u; h; p1 R
  60.     rt_kprintf("will connect...\n");+ X) S- ]7 G0 D; v& F
  61.     if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
    + p9 b; B" ]3 @9 C: c2 Q# ]
  62.     {
    ( \* G0 R- {" B& ^2 j& B% _
  63.         rt_kprintf("Connect fail!\n");' U  Q3 f3 M( h
  64.         goto __exit;
    9 ^7 U, [* }/ n7 z
  65.     }
    : q! ]3 m* r" v
  66.     else3 ~/ _* g- f1 V' ^* Q* V" d# p
  67.     {: ~/ p6 Z+ p$ o' o) C
  68.         rt_kprintf("Connect pass!\n");0 n2 J) w& T# _" Q; `
  69.     }( v9 o; ~4 \, g1 B9 e, Y; _

  70.   y* Z6 v/ y5 N; A" [3 v4 [
  71.     /* 发送数据到 socket 连接 */
    $ |( i" e2 }. v6 w/ Y! L8 Y1 o
  72.     ret = send(sock, send_tcp_req_data, strlen(send_tcp_req_data), 0);
    / q: v& [" T* J, E" K. K' v* N0 x) V5 X
  73.     if (ret <= 0)
    + w( B8 n1 P  U& l
  74.     {
    ( }  f- L- M  [, r/ E/ R
  75.         rt_kprintf("send error,close the socket.\n");
      @& s/ o0 Y" k# L  H! g+ O( l
  76.         goto __exit;" ]8 q6 O$ x2 |0 \
  77.     }/ Q. o) }/ R. u: [
  78.     else
    ( h1 D( V8 K1 j, w
  79.     {
    3 B( ^8 Q5 n0 l. q
  80.         rt_kprintf("send pass!\n");
    9 Y, q/ H# w9 ]1 [0 n9 Q9 v- u
  81.     }7 N& e5 s+ o1 r1 T- o/ _, |
  82. 9 k0 p) g/ q* _6 ?6 o1 D' l
  83.     /* 接收并打印响应的数据,使用加密数据传输 */! t8 ^& }+ V2 F$ L' ]- l
  84.     bytes_received = recv(sock, recv_data, TEST_BUFSZ - 1, 0);" }" Z3 l6 S4 J
  85.     if (bytes_received <= 0)
    9 O2 V  I8 M2 b- U
  86.     {
    3 u0 {# \& k# N& `5 x1 j
  87.         rt_kprintf("received error,close the socket.\n");0 s6 G. N+ {* C2 ?
  88.         goto __exit;) ~4 _- W+ x1 ^& q1 z' o" c5 M
  89.     }
    * `. L9 E/ J% Y/ Z
  90. " O' [6 @8 B) S, v: w( ^
  91.     rt_kprintf("recv data:\n");8 J: t8 S* W9 P
  92.     for (i = 0; i < bytes_received; i++)7 J3 E1 z! I5 q& z8 H
  93.     {
    6 Z) k  n/ F$ F' Z
  94.         rt_kprintf("%c", recv_data);
    " x: f9 P1 d7 s# a% j0 V8 T$ z" k7 D/ Y
  95.     }! {  B' t! t3 `* q7 D+ x9 g5 Z
  96. % g# f, ^. U# {1 V' o  t. A* ?
  97. __exit:
    # \0 H; o4 X6 R
  98.     if (recv_data)
    ; o( T: _" _  ^* \4 {" W0 i
  99.         rt_free(recv_data);
    ) p2 U5 T: t# e& L; d1 Q- A0 N
  100. + ~+ P6 u9 v, I
  101.     if (sock >= 0)" n0 t2 d8 j+ e; |# F  c% s
  102.         close(sock);; n( r2 o# p6 }' b% p9 [: r
  103. }
    . |* e( {4 v! B  l* ^
  104. 9 ]- j& f5 Y  d! V, J- w
  105. void tcp_test(void); B0 s: E, r' U+ M0 B% q
  106. {
    - T, Z5 d) V$ a$ G/ C  S- w0 N
  107.     rt_thread_t tid;
    & p0 ?: G5 E! f: c/ K0 ^% E
  108.     tid = rt_thread_create("tcp", _tcp_test, NULL, 4096, 23, 5);+ m% M6 e9 T+ ?- M+ p* J! Z" O- V
  109.     if (tid)/ M* k! Y! b) H, d; h
  110.         rt_thread_startup(tid);
    + h3 t5 W2 \5 b# Z
  111.     else& Y% i8 A# ^6 f: @' ?" g
  112.     {1 B+ Q7 K  W7 n; {$ `! Y4 x
  113.         rt_kprintf("tcp thread create failed!\r\n");
    ! l' J# N! P  ^3 a# P+ v3 o3 R: ^
  114.     }
    & D: ?9 \6 g' g9 ^% u
  115. }# l- E' r; f6 {1 w
  116. 4 Y, S# R7 W+ k
  117. #ifdef FINSH_USING_MSH
    ' m0 e1 P* _; O4 I
  118. #include <finsh.h>
    7 h. E( r5 @7 O9 [4 v
  119. MSH_CMD_EXPORT(tcp_test, TCP function test);) }* E" g* ~9 F- n# G
  120. #endif /* FINSH_USING_MSH */, D0 [+ \- ?# k" I0 v
复制代码

7 \/ T( C" z' h; ?- b7 O9 ~2 t0 |; E+ J9 C# E7 A5 ]  b8 G7 a5 z
如果你也是使用 RT-Thread,那么直接复制代码加入编译,然后在 MSH 中运行既可以:, W5 l6 f0 r9 b6 O2 [5 @* |
0 |  z9 L- U0 @, j8 \2 k, b
  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 ~5 d( x1 E1 v. T% s, R6 j$ @+ @7 i$ Z2 v1 m
从文本编辑器复制代码,粘贴到论坛里的代码插入标签,提交之后会插入到当前光标位置。0 q. M2 R! }4 Y& K8 C- i0 M
这个时候你看到的代码格式是乱掉的,没有空格缩进等,不要紧,保存提交帖子即可,这个时候会发现,代码格式显示正常了。
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版