本帖最后由 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
- #include <stdio.h>
1 I7 w" x+ v& M3 y0 a/ R) y4 p - #include <string.h>
2 Q7 E" L) S2 w" R ] - #include <rtthread.h>9 H8 [# n% j* e. k4 z5 f G9 d7 W
- ! D; H; J, W: u3 d+ e
- /* 引入 lwip socket 头文件 */' I4 J( O6 L4 z+ L, W# b5 v
- #include "lwip/sockets.h"
+ K8 N* m3 j B0 b ^1 ~- T( t$ p8 W - #include "lwip/netdb.h"
) Y3 T* q9 ~2 n7 _ - #include "lwip/sys.h" m" k9 M! v3 M7 T
/ s. |( n- q2 m7 Y- #define TCP_TEST_HOST "your host or ip addr" /* 输入你的 TCP server 域名或者 ip 地址 */
- k% h4 Z. D; o# [6 r0 P) e - #define TCP_TEST_PORT (80u) /* 输入你的 TCP Server 断口号 */0 g9 B! n% B9 ?& L! a+ Y# z7 C
- #define TEST_BUFSZ (1024u)
) L, }* c% h! C$ l6 \( D3 f - . G( }" `' f4 S7 g- I
- static const char *send_tcp_req_data = "Hi, I am from tcp client.";
- z/ y- z; `3 a0 g4 ^' w
0 `) T6 @, n$ `$ J) R; U& G1 x! g- static void _tcp_test(void)0 m. k4 a3 Q4 l* G8 E
- {
& ?/ M2 {& I c3 ]4 l - int ret, i;
4 e+ |) y5 Y7 t2 O2 U - char *recv_data;
3 n8 ?# N. _6 \$ v1 n1 p - struct hostent *host;: G! r3 t" N5 c, h3 k
- int sock = -1, bytes_received;
; N& r3 T: f1 t, Z" t9 q0 R) P/ ? - struct sockaddr_in server_addr;7 i$ f- d, `& [, w6 F/ Y
7 I6 z. h3 ?5 r" f- /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */) U; x4 B# z% {5 `3 r
- host = gethostbyname(TCP_TEST_HOST);) \" h$ T7 y: V5 l- ^* e; p( b
- if (!host)) X' h2 f$ p% {$ b) |' ?5 @
- {
! Y. o, y1 n: K8 A8 M: G6 g - rt_kprintf("gethostbyname failed!\r\n"); K; R6 l- p# l0 E
- return;
5 { r. y0 b4 x - }+ ^& R. |9 G* M' y+ p% a% n
- else
9 b8 X8 b) g9 m4 Z - {; B3 J4 J- U; l5 L* n9 j
- rt_kprintf("gethostbyname success!\r\n");
5 ^% |/ T" [: |; V# c6 i7 i - }
* n% y A* I4 Q( v1 J4 G0 I! O& a
+ h0 V9 X+ |) ] r. c- recv_data = calloc(1, TEST_BUFSZ);5 z# A6 x( V& [2 E
- if (recv_data == RT_NULL)0 I% I8 N& D2 u S2 @$ P5 U8 b
- {
- @& M- H$ \0 j3 { - rt_kprintf("No memory\n");6 t( N" f) ?" G& s. Q& F' G2 ^
- return;
; ] _' q. X. s) b: H8 y" R1 \% T - }
- h3 a5 |; J$ f$ l" [( h) s - % R* J9 P4 F( a% `
- /* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */1 { Z. P0 j, q+ N# G- h9 j
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)1 @- d9 S/ l* L* m8 T, i1 h
- {* d0 {0 v# m2 H5 W, R( v" [+ d! m
- rt_kprintf("Socket error\n");
! p/ m: f. m+ ` - goto __exit;9 \7 C$ W$ V9 _, w! b+ E, _
- }8 B& Q2 \3 V: d1 G; o+ I0 R& s
- else
3 p' P" A. r& o+ F' `2 F' u6 Z) a& ~ - {+ | v9 A+ G1 [4 {& o/ G
- rt_kprintf("Socket pass\n");# b$ J$ _: J! X; J" O: ?
- }( G! h6 v9 m ^
- / `7 i- z9 j1 b7 \9 y# E
- /* 初始化预连接的服务端地址 */$ V# d* T. f3 ~" a. g
- server_addr.sin_family = AF_INET;, v4 C$ P. I4 ^
- server_addr.sin_port = htons(TCP_TEST_PORT);0 t: @! a/ N# V# ?. B/ \ C
- server_addr.sin_addr = *((struct in_addr *)host->h_addr);
! x2 b$ w5 k) w - memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));4 i3 Y. h" H/ t6 D7 \% {( e
8 y9 U/ p, M0 b2 @8 c/ [ s- rt_kprintf("will connect...\n"); x4 M4 L3 _9 J* v8 L( _
- if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
4 `3 ^2 a+ j( Z0 {( H5 f4 R* j - {
9 a/ R; U' r0 V0 ~& K4 t' Q: F - rt_kprintf("Connect fail!\n");# r4 B, P; g; U1 T, V0 v2 U. H4 |
- goto __exit;' k% a; Y$ H3 @
- }2 R& s9 ]7 M) l/ k; r" ]$ W# N
- else
9 z* t0 L0 b8 R3 q - {
, ]4 t. q H' p9 t. s - rt_kprintf("Connect pass!\n");2 [+ n: O2 _, |: o5 L
- }
( o7 i- p4 [8 h) P - 5 g6 b- D; D7 V: ?% }) E! |
- /* 发送数据到 socket 连接 */
7 w4 B3 S& y2 ~0 O8 T2 Y9 d - ret = send(sock, send_tcp_req_data, strlen(send_tcp_req_data), 0);
# F+ k$ g( \9 R+ f2 ~ - if (ret <= 0)& ?% W$ Q8 I! f: t) D
- {, }- | }2 c d, O+ M3 \- B
- rt_kprintf("send error,close the socket.\n"); A8 }8 E) `& e7 [+ R- H
- goto __exit;' ~. z5 V. D# H
- }
0 V H5 n1 W2 o7 V8 U; @2 u - else
9 S! E) f, I. r4 f+ q# q - { h( O. ~8 c" i a
- rt_kprintf("send pass!\n");
) ?8 f7 Z: ` x D8 |* _ - }
0 A( d: r- H8 g' i' r
! i& G3 f8 T% j4 T, [% v* ~- /* 接收并打印响应的数据,使用加密数据传输 */, |6 c1 C8 t& U4 ~
- bytes_received = recv(sock, recv_data, TEST_BUFSZ - 1, 0);
K) M/ \5 o; j" w& i( a$ V; ^ - if (bytes_received <= 0)
( ~8 Z, `* h- N+ k% _& W: L - {9 @" Y0 A6 U) C$ Y' W& y& C
- rt_kprintf("received error,close the socket.\n");/ o' _4 d; j, ?& i, l" ^! U
- goto __exit;) G2 n- ~! d+ I& E
- }
, v; T4 |1 T4 J0 T, c( E( d2 m$ F* I
/ Q4 I( g n' \( v2 X- rt_kprintf("recv data:\n");5 e+ a/ s& H' U+ j& e+ D
- for (i = 0; i < bytes_received; i++)6 b+ F' R: U) t8 d" X: s* J
- {
$ u/ R$ D' y, o' ^3 {5 l, R4 X - rt_kprintf("%c", recv_data);+ N0 g8 [) y+ c* @
- }9 H! l/ U# |3 |/ ~, P
" p" ~) n* c/ O# Q1 c1 w5 n- __exit:# J' D( x- ]$ u$ C' b2 H: J
- if (recv_data)
C* S; |; c& A( k3 G8 n - rt_free(recv_data);
' X% {4 n3 }. t) w, Z d1 ]8 f& E - 2 L2 _: ]7 E R1 [8 Q! S j
- if (sock >= 0)
& ^! U' l' B7 P) n- \ - close(sock);3 @; X" d4 o6 T6 Z8 Y+ h* X
- }
6 i7 ?6 ?. s4 Z) M6 V
, t$ ?. h, n4 b0 a; Y% y2 w, @- void tcp_test(void)! p$ _# D( s+ S1 a- [9 K
- {1 }( b; m7 U' v, U" l
- rt_thread_t tid; f/ R r! i' y
- tid = rt_thread_create("tcp", _tcp_test, NULL, 4096, 23, 5);. H6 ?7 ^0 m/ e! H. i4 C
- if (tid)$ q2 n1 P4 g1 l9 i
- rt_thread_startup(tid);
3 v% X2 T: x& B1 q - else4 Q' l& K$ w/ o9 t: m$ _
- {
5 x% p( _5 u, J( C* ]' ^ - rt_kprintf("tcp thread create failed!\r\n");
3 [5 e( r/ ^% V/ |' b4 y% y - }
! G2 R. ?0 ?- r: m* O# t( ]& c1 u0 j% U - }
4 W e3 k4 m6 R/ z" P) @
6 w. g$ n7 C; M% x- #ifdef FINSH_USING_MSH% n* M& ?* r% x9 V
- #include <finsh.h>" E b- ^ i8 x) U6 z% K: `
- MSH_CMD_EXPORT(tcp_test, TCP function test);, @5 Z* e2 {$ q6 y4 d
- #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
tcp_client.rar
(1.32 KB, 下载次数: 3)
|
从文本编辑器复制代码,粘贴到论坛里的代码插入标签,提交之后会插入到当前光标位置。# l# x$ @. X' B( k5 a
这个时候你看到的代码格式是乱掉的,没有空格缩进等,不要紧,保存提交帖子即可,这个时候会发现,代码格式显示正常了。