本帖最后由 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
- #include <stdio.h>$ O) M0 d" h( ~) ^- |# s
- #include <string.h>* X" t% g" J6 F* E$ h' e7 r
- #include <rtthread.h>) [) G' E# ~8 a# t J
- 7 v# u0 O7 ?- U" w, b# P# B; ?1 M
- /* 引入 lwip socket 头文件 */, b* ~+ O3 C2 F* `/ \* e
- #include "lwip/sockets.h"
+ g" W0 W; f9 z+ Z6 |% w - #include "lwip/netdb.h"8 N j+ Y0 r9 ^) D; b9 m# q
- #include "lwip/sys.h"
* W: d1 o+ [7 P9 ~# b - " l* ^* H8 Q; W) c+ A
- #define TCP_TEST_HOST "your host or ip addr" /* 输入你的 TCP server 域名或者 ip 地址 */
# O, y5 J$ D$ a( L' f6 R9 K - #define TCP_TEST_PORT (80u) /* 输入你的 TCP Server 断口号 */
) O: ]6 F! h% W i. | - #define TEST_BUFSZ (1024u)1 z9 Z' _; z' Q% w( w3 o& [
- q$ J8 d6 b I3 m- H; R- static const char *send_tcp_req_data = "Hi, I am from tcp client.";! D+ Z ^ X( X8 r3 I' q' b
- & e0 O7 ~) L6 q7 E1 e! K
- static void _tcp_test(void)* `/ P' H7 ?( ~% C2 n" | p
- {
/ h1 s9 ?8 W4 t: _$ { - int ret, i;* T+ L7 U( [7 j/ X
- char *recv_data;6 E% ?3 I) r; x0 z1 R
- struct hostent *host;
; j0 n5 V3 a8 [) K& t! W - int sock = -1, bytes_received;! K' a3 S! q n- J
- struct sockaddr_in server_addr;! n5 v- X- y0 _
- U# n5 ~& o# l; ^- /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
* ]( ~9 M: I4 \5 C - host = gethostbyname(TCP_TEST_HOST);/ U# ~" w- S3 x% {& J# q9 X
- if (!host)9 d7 Q) ?% ]0 N+ s0 |( D% p4 \
- {
3 @, G! z: r U2 b+ o* k( X$ ~& B2 _ - rt_kprintf("gethostbyname failed!\r\n");( W5 P* U) \+ {3 D
- return;1 x, e. ~' m) w9 X
- }
- `3 I& j; f) Y - else
) ?+ Z) c4 r* F4 e" Q& L; y - {
O1 e9 x( N1 u% W7 K - rt_kprintf("gethostbyname success!\r\n");. p* A. \/ C* w
- }
" E- h$ G( l/ N( k) r# j( e4 ^ - 4 N; k- S t W& r$ H
- recv_data = calloc(1, TEST_BUFSZ);
' x7 f6 u1 I/ [. C - if (recv_data == RT_NULL)) U* y: Z- x0 ^' L4 F
- {
7 p0 O6 F# Y0 R/ h% o3 P5 L - rt_kprintf("No memory\n");
$ _: e9 ~5 |5 ]' P' A - return;" ^. b! \1 H- |4 a% ~' W# F
- }
( z! e1 q1 c$ v) W - & l' r g* e/ I
- /* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */0 ~! x. C% ?- p
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)6 Y m; c0 C- D- f D C
- {
4 E: G3 U0 X- _, _ - rt_kprintf("Socket error\n");
& Q3 i3 r+ W- B9 G, q( I. O2 j - goto __exit;
% b, s, Q1 C4 N9 k; l9 | - }5 Q& S3 R4 R1 P# S7 Y6 v$ v- R
- else
6 B9 `) o: \- {' a - {
4 i& b2 v) ?& m# ~, N# ~ - rt_kprintf("Socket pass\n");
i) K$ S$ v' T; P7 { - } m4 X O+ M0 ~3 j
2 A6 J9 z# X) e* F, B1 ~- /* 初始化预连接的服务端地址 */
0 p, M& f5 Q1 V9 { - server_addr.sin_family = AF_INET;
9 r8 u$ C6 h" D/ J5 d - server_addr.sin_port = htons(TCP_TEST_PORT);2 N1 Q \8 l+ C* A
- server_addr.sin_addr = *((struct in_addr *)host->h_addr);
4 t6 [ N) u; _* {8 k; r - memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));2 U! \7 _( f p! q! g. p0 O
* b" ^4 H3 \) l* h& U- rt_kprintf("will connect...\n");
" s* y* [ b) b+ a# A) Z: ?, d - if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0). w. I, e0 p& w( v
- {" c$ J7 \* E L3 I5 _1 |+ J8 E+ ?& ~
- rt_kprintf("Connect fail!\n");
3 x' @& J7 E9 R4 `0 P" O; H - goto __exit;2 l; E0 S- }; F5 E: `# k
- }: E7 w5 _# c K7 }) X
- else
, m, H+ H9 K) G' n. \! [7 Y - {& ]- |% N# N6 W+ }! G6 @( ?' Y
- rt_kprintf("Connect pass!\n");( w# L" \( t9 g! Z5 Y% O4 i2 B
- }' ^! ?8 b# v- t
- * D( d3 V0 [% W5 q- V |* u7 B' Y, g
- /* 发送数据到 socket 连接 */
! J" u- p" Z2 _* y3 \+ l4 m - ret = send(sock, send_tcp_req_data, strlen(send_tcp_req_data), 0);
$ I4 S {! R* |! g& T - if (ret <= 0)( A% N% _# |- U* d( w8 j. x
- {
# ]+ M; k1 ^2 c$ {" a - rt_kprintf("send error,close the socket.\n");
# x/ d- K( t1 G( w3 W - goto __exit;0 e( y! B0 f9 {; c! C. a% ]! I0 s
- }1 @& X+ ~* ?5 H1 p* Z' Z! b8 V# X7 E
- else N; j( E9 }. `4 V- K% m) q, s
- {4 `0 l9 Y" w5 @' K# |
- rt_kprintf("send pass!\n");* W- ?0 Z- [' @$ d/ L1 o
- }5 j E0 F- c5 h9 |5 s/ d3 }- c
- 2 {% D6 F+ O( Y A
- /* 接收并打印响应的数据,使用加密数据传输 */
5 L& z" k: L0 j/ Y9 u2 _9 o - bytes_received = recv(sock, recv_data, TEST_BUFSZ - 1, 0);
l1 |! i- |6 B! R4 E# ] - if (bytes_received <= 0)
% {1 M% W" r& |- W) C - {
) s M {, c- C+ K9 h- V' C$ }' A - rt_kprintf("received error,close the socket.\n");% M# ~0 x6 k& K7 D
- goto __exit;% J5 T! P: M0 I& U2 ^) K e0 p
- }
) P: P* H2 D9 @; B' c- w! a - 1 U7 d% q1 }; b; L, G0 J1 l
- rt_kprintf("recv data:\n");
' }! b) k/ w% @& t1 H - for (i = 0; i < bytes_received; i++)
6 c, V; u0 u& m Z) d4 n0 @ - {( r \, L8 l; M, C( Z/ P6 k
- rt_kprintf("%c", recv_data);
6 X! R" }5 z8 e, Q4 Y; X! _ - }
6 k& t( Z3 r# { z0 E
* o$ [2 G$ P( F2 ~( e9 a' l- __exit:. a* ~' S# Z7 {
- if (recv_data)
" {4 y2 a4 h$ l# u, _4 K - rt_free(recv_data);
; D2 |5 V% Y! A g$ z" ]# z7 R! G - . l% x) p) A+ ^5 u/ Y5 k3 X1 B: H7 ~
- if (sock >= 0)
' G0 V1 ]# _) t h7 C8 |+ h6 N0 S" Q - close(sock);
( J/ A+ F9 \, Y1 @& Y - }
* C: H% p2 V; r) i9 \/ K& E - ( ^7 P% N: d6 s) v
- void tcp_test(void)
5 R5 j3 ^ ?+ k9 c* s - {
3 I& P0 d4 n9 [& q - rt_thread_t tid;
; k9 q! t! x) j8 j9 \# P) s - tid = rt_thread_create("tcp", _tcp_test, NULL, 4096, 23, 5);3 _# L0 R" O3 T" |
- if (tid), ]! T5 s* j8 u4 n
- rt_thread_startup(tid);3 b( m0 g4 v4 ~; O5 A; U* }- i
- else
7 ~& x6 S% r# S. A% i) H) I - {
4 V ?# e# ]1 c. q5 j - rt_kprintf("tcp thread create failed!\r\n");
2 T( t2 A$ r/ t0 w( B) A& |' Z& I! J - }
8 z" k) K- Q$ Z- @! M) a - }
7 y. u' T" i; Y3 i n
4 j- c: e8 \) ]4 A U) N+ p- #ifdef FINSH_USING_MSH
9 v% A. T3 B1 l - #include <finsh.h>. n1 r3 w* X) T( d% l6 K# i
- MSH_CMD_EXPORT(tcp_test, TCP function test);
4 n- U0 d, M0 |9 v - #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 ^
tcp_client.rar
(1.32 KB, 下载次数: 3)
|
- ]0 \+ B. |! I! P* Q
从文本编辑器复制代码,粘贴到论坛里的代码插入标签,提交之后会插入到当前光标位置。
这个时候你看到的代码格式是乱掉的,没有空格缩进等,不要紧,保存提交帖子即可,这个时候会发现,代码格式显示正常了。