本帖最后由 murphyzhao 于 2019-6-28 08:53 编辑 ( `" Y2 O1 F* Y, G- f; P
$ [! Q ?: ~* f& i. F
现在都 lwip 210 版本了,无奈,因为客户 SDK 的原因还在捣鼓 lwip151 版本。
3 ?7 S, l1 I1 m4 @& s$ k5 s
! j# J$ [1 f4 s+ x4 L0 c. f将客户 SDK 升级到 RT-Thread 系统的时候,发现低功耗部分与 LWIP 有耦合,不能直接使用 RT-Thread 移植的 LWIP 组件,也就意味着,我不同享受 RT-Thread netdev 组件和 SAL 组件开发的便利。
, w' O0 F" @; ~3 j9 d9 s
+ u% J, u1 b/ J, L {/ G" E于是,给自己挖了个坑,把 LWIP151 版本对接到 netdev 和 sal 组件上
C" I* W* u' S' m) r+ P- T/ N a0 D/ W- ]' o1 v# c* r5 E
为了测试,捣鼓了一个简单的 TCP 客户端程序,后面有时间也把对接 RT-Thread netdev 组件和 SAL 组件的过程也给分享出来。
8 N/ E' P0 `7 y5 \- g7 _
9 P' R: _7 s" |! w这里提供的代码基于 BSD-type 风格的 socket 函数接口,你可以在任何支持 BSD socket 的平台上使用这段程序,当然这段程序也可以在包含了 RT-Thread SAL 的使用方法,引入 SAL 相关头文件。6 z+ M) I' ^6 h W* Y
4 _5 `% i4 S" G# e& s
- #include <stdio.h>
8 m( C2 e7 u4 J9 G8 o - #include <string.h>
; x% o# r$ r4 a7 X/ q! Y( l - #include <rtthread.h>+ P) T! j1 Y; z H& v7 z
. P2 P* a1 q+ q: U/ [" C- /* 引入 lwip socket 头文件 */6 L: a, p7 y6 ~
- #include "lwip/sockets.h"
; \' U8 f4 N# U - #include "lwip/netdb.h"
5 S- I3 g* j- z1 v4 [7 D - #include "lwip/sys.h"
$ u; A4 `2 E: m5 S e+ g5 O: l
, N7 e) B, I% k7 g1 ^- #define TCP_TEST_HOST "your host or ip addr" /* 输入你的 TCP server 域名或者 ip 地址 */2 N( t/ u8 M( T& [( U
- #define TCP_TEST_PORT (80u) /* 输入你的 TCP Server 断口号 */9 G4 G2 _+ Y. j% a
- #define TEST_BUFSZ (1024u)2 w6 U' A+ V2 {
- ! ?. V! s+ U6 b( D/ _1 ^
- static const char *send_tcp_req_data = "Hi, I am from tcp client."; H) z7 s' l# H4 @3 ?, ?1 ]# |
- . g; v' I5 J6 R% m% Q
- static void _tcp_test(void)
/ `) q, R$ l$ e0 T# E# ? - {
# C( U) i9 L$ ~! ^ D: p* ~; w - int ret, i;3 l6 L4 [- B" h5 d& F' ^3 K
- char *recv_data;# J+ o! E5 C: @% }6 l' k3 W
- struct hostent *host;. X" M- F- b0 |* R
- int sock = -1, bytes_received;
( a4 L8 b7 z6 R - struct sockaddr_in server_addr;/ A& P9 ?% t6 c4 X* b
- " Z0 ~/ X$ D' y5 W. \% w( U1 n
- /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
0 [; k+ \3 L. }5 j* b0 Z2 j o - host = gethostbyname(TCP_TEST_HOST);
0 S) M. f; y0 K- |7 |4 O - if (!host)
7 {4 |5 ^4 \1 h5 G9 r - {
: T/ u L2 c4 K8 R1 U - rt_kprintf("gethostbyname failed!\r\n");0 D3 Y! m v7 B/ Z# Z0 L
- return;
F u' F; L/ S/ V0 P* W - }3 \& n' G/ m; ^/ e1 ^3 l
- else
* X- B, e5 Z6 q! L9 n& B - {" `8 P! W% h, _: ?$ h3 s
- rt_kprintf("gethostbyname success!\r\n");
1 m" ^0 B2 b, J, {0 a9 W: b3 p4 j4 { - }% Q8 J1 R0 q' G/ G& F7 o8 ]
- % Y5 F4 i3 k: v7 N& |: f
- recv_data = calloc(1, TEST_BUFSZ);) H; Y, m5 ?9 c+ E6 K& m$ R9 ]% k5 n
- if (recv_data == RT_NULL)
+ u, z0 z+ _8 u/ X# Z9 Z - {
; K' M7 x% P+ r# {4 E - rt_kprintf("No memory\n");
- i+ n0 c2 c6 S+ B; J, L4 R* Z! ~& R - return;" Y2 V% D8 u8 s9 h
- }& ~4 a* c) z3 d! L
( g; V& a' H, I9 P ]# }- /* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */7 X' F; y. C6 G# R
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
0 f) h2 `8 C5 C - {1 L1 w8 W$ R, p2 x4 g/ h
- rt_kprintf("Socket error\n"); O8 p( M( o$ f+ R! v5 ^: m* t2 }" }
- goto __exit;
& i& J- l7 ~) b/ C* G$ @5 v( C% ` - }/ v* ]' e5 O I" _
- else
$ R: O7 p) ~" F0 ^" T/ X/ f# g - {
0 K# v2 j( N4 ]& ~ - rt_kprintf("Socket pass\n");
) |( M) C3 T9 |2 v% M- l/ L% ~ - }
( e/ Q* ]3 o K& E: u. x! x+ {- ~
- ?9 }4 E7 A& W, F) \$ C- /* 初始化预连接的服务端地址 */, H7 O5 o' J0 T$ p6 ^# `% n( X
- server_addr.sin_family = AF_INET;
) u: b' U! U! s$ A - server_addr.sin_port = htons(TCP_TEST_PORT);
7 @- r3 @2 o+ q% u6 F! m) [ - server_addr.sin_addr = *((struct in_addr *)host->h_addr);
1 b0 \* G3 A* s( ?% Q* j - memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
' C0 d# t+ l# f) z2 {6 | - 1 \# }, u2 d- c- |% g& V
- rt_kprintf("will connect...\n");
/ [6 I3 v$ ?" G5 J& f# [* M% E* F - if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)& V* X& ?; j: S. O* e- {2 ]7 B
- {
; g8 ~2 Q* H9 @2 J - rt_kprintf("Connect fail!\n");+ o7 P z O/ y2 ^. f' _6 I" R/ }
- goto __exit;
b3 W0 ^* Z. h! j# g( w9 m0 L - }
# B7 |, E, W) h+ ?/ b. C/ Z2 [ - else( J2 G" z& M! v) H
- {7 H2 W7 N( G$ b1 n# M6 V: O! e
- rt_kprintf("Connect pass!\n");
) W3 H# H) R& K2 L* C. A$ I - }# Y) N `/ y! e: I& d7 P
" X( A$ E' c2 E6 ?+ }7 D2 Y- /* 发送数据到 socket 连接 */9 i+ Z5 f6 Z. `3 X+ J& @
- ret = send(sock, send_tcp_req_data, strlen(send_tcp_req_data), 0);
* a: M0 J& _6 J/ K7 b0 I" B - if (ret <= 0)
' E5 H; S6 w, s0 x8 R( _( v - {3 n& `; z4 \7 `) B2 r; ?
- rt_kprintf("send error,close the socket.\n");5 ~' s6 M+ l" J* V( k. W- B) Y$ E1 V
- goto __exit;' R# _! _" G0 i8 B' v" `" n
- }: T! |$ A( f' L8 O0 r( `# L
- else
; V T( Q9 f' y q+ I C5 o - {/ Y* y3 T# S6 T7 J
- rt_kprintf("send pass!\n");2 Q' q* H( x% w
- }
/ S( s. a w2 l* d
! j2 }; Z5 P. O6 K! z- /* 接收并打印响应的数据,使用加密数据传输 */
8 B- Q0 `9 ^/ |, R* y, H) B- b - bytes_received = recv(sock, recv_data, TEST_BUFSZ - 1, 0);0 X( ?: t7 M1 l7 D* Q' y
- if (bytes_received <= 0); m+ I) h& l" {/ Y
- {/ ^9 S# i/ b0 V9 e, \
- rt_kprintf("received error,close the socket.\n");4 X% p! R' o5 Y* \0 t+ t* T
- goto __exit;2 m8 \' p- `, i* s# f' I3 W
- }
+ @' X3 o, Q! c7 N$ z - * q' Y$ N( Q- @4 Q; w0 n
- rt_kprintf("recv data:\n");/ B0 k) P# g' H! F# q
- for (i = 0; i < bytes_received; i++)
- L7 @4 g# S' c$ M6 r - {
" L4 D1 _* X0 i% i$ O7 M5 I2 E - rt_kprintf("%c", recv_data);
; x- F2 Q& c$ C; @4 h - }9 K& y7 T5 T2 f
- 3 S* R: o/ Z& {
- __exit:0 A& j" b7 T" X0 n8 D
- if (recv_data)
8 e3 \5 i2 H6 h. Z - rt_free(recv_data);
1 S& Z1 X7 j- b a- @) y& h7 e - / Q9 D3 }* o' b+ b9 M; g
- if (sock >= 0)
6 b( O/ k. ~" F* x- a - close(sock);
# ]( x$ f6 p! |% D3 z - }
% _7 b# Z# G& U% n - 6 J% e: u! j& K2 ?1 Z# H5 O. |
- void tcp_test(void)
: E) c3 S) U. E8 e/ B - {5 I, b( I- h4 ^" Q! O
- rt_thread_t tid;
{ l8 g0 Y7 c% a C - tid = rt_thread_create("tcp", _tcp_test, NULL, 4096, 23, 5);5 N- d4 L4 k' f: I
- if (tid)
/ M" y9 y& T1 |$ x/ @3 W5 | - rt_thread_startup(tid);
. T9 f7 h; }2 ` - else
! r% a% g5 ]. ~1 r! {0 N - {( K* [! s. p- G1 x" s0 m: w* x
- rt_kprintf("tcp thread create failed!\r\n");) d: u7 N- a& W4 c3 d; `( G. J
- }
$ h! U$ ~( L! k$ _) V - }$ z, o" `( | F% \* x& s
- 3 \2 P1 l. T( P8 l S& A/ ~! o/ P2 G) y+ b
- #ifdef FINSH_USING_MSH: J* D: s/ J2 t3 W
- #include <finsh.h>
7 R8 H; j; n9 i& ?% U - MSH_CMD_EXPORT(tcp_test, TCP function test);
+ u0 M# k8 F% a) z, r) N" L$ X - #endif /* FINSH_USING_MSH */
' u& g3 s4 c$ @5 T7 _* U4 @
复制代码
* R1 z) I0 J0 r9 ~$ [. Q; K
- h6 S& R/ f9 I如果你也是使用 RT-Thread,那么直接复制代码加入编译,然后在 MSH 中运行既可以:% L2 m- j( E3 K% g: `
! N1 P f, b; I
tcp_client.rar
(1.32 KB, 下载次数: 3)
|
9 w- l o0 [' l& ~8 S. ?6 r
从文本编辑器复制代码,粘贴到论坛里的代码插入标签,提交之后会插入到当前光标位置。0 ]3 O8 R. ~ v& h/ U8 ^
这个时候你看到的代码格式是乱掉的,没有空格缩进等,不要紧,保存提交帖子即可,这个时候会发现,代码格式显示正常了。