找回密码
 注册
关于网站域名变更的通知
查看: 328|回复: 1
打印 上一主题 下一主题

怎样用bash做个tcp客户端

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-3-19 10:02 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

' B. [. L% z* X+ W- v& u日常做后台服务开发,总免不了要写测试客户端。但是tcp客户端写起来其实还是比较罗嗦的,各种错误返回,各种异常判断。。。。而我们通常并不是要写一个健壮的客户端,我们只是要一个能用的客户端来测试服务端是否正确。
8 H7 K% V5 e& w3 K& D& i' v    这里给大家介绍一个简单易用的方法:用bash操作socket!很酷,是不是?0 I# _& e  s2 x) ^: ~5 M. v; ~

. r3 |+ ^  X# i' [2 \0 M
' s& z4 X# M( x# x( E    man bash,查找tcp关键字,可以看到这么一段内容:1 E4 P% |9 J& y7 ^. [. l  Y5 I
1        /dev/tcp/host/port
* A& \$ p% [. _1 ^2               If host is a valid hostname or Internet address, and port is an integer port number or service  name,  bash attempts to open a TCP connection to the corresponding socket.
3 w/ a1 x# b0 o" V! m3 k. f6 }* i# D1 F& Z
    把其中的host和port换成我们要连接的IP和端口,就可以用来建立tcp连接了。如下:5 B; |2 H8 L& k* D9 C' [0 Y

5 N  E7 C$ [% C" \2 x" k1        exec 3<>/dev/tcp/10.6.221.149/9865
: p5 h- t; L' w# G6 ^1 R, p, K
1 j: P5 d% B, S: o! R
; O0 W5 ~6 t2 d4 e  r$ o% A    上面就建立了一个到10.6.221.149:9865的可读可写的socket连接。1 }4 b7 T% A  a. `
    其中3就是指定的连接后的socket fd,由于0、1、2分别被stdin、stdout、stderr占用,所以可用fd最小从3开始。- a% j7 B4 @8 l8 O% F
    ip换成域名其实也是支持的,比如
9 Q7 s: I& b4 D0 o4 \8 G2 ~& ~5 [8 x1 S, z) p' H$ p
1        exec 3<>/dev/tcp/www.xx.com/9865     注意"<>"前后不要空格,否则会出错。
- j3 r  ?0 g+ G3 Z
; E3 Z5 H! m& }: ?: Z    发送请求其实很简单,就跟往文件里写数据一样。例如& l+ V. ^* I/ ^9 T$ m
" y/ l2 i. s( q, Y
1        exec "hello world." >&3" k: p7 |- b) Q7 Y, K+ O
8 m4 o5 e- L" _9 {5 t

$ z3 f& f4 u1 h' o3 |$ C, z3 m    如果要发HTTP请求,那可以这样:
  W2 C  S+ o5 G4 \9 J$ W# e' k! H4 C
# O6 E9 x% G/ r3 H& q) s9 g1        echo -e "GET /crossdomain.xml HTTP/1.1\r\nHost:www.xx.com\r\n\r\n" >&3
1 ^4 o. O, v  Q) h: m
6 S+ d, @. j- T
- W8 S  `3 K+ d+ Y$ @+ S     二进制请求可以这样发:7 o$ R. k' N6 q0 `% G

+ ?$ e+ g7 M( B1        cat bin_data >&39 M2 N1 y% l' h* ~4 ^, \

* Q( N* G, H( s) `2 I) T4 L- X7 ?( U$ q3 f+ X" O
    其中bin_data是已经写好的二进制包数据文件。
8 p& [' p. Y6 e 7 G$ u( C2 f; p  r; \* z" N
   读取服务器响应跟读文件差不多,可以这样写:! \& @3 w4 [' T0 k2 @  y- ~; d

! q4 \* F- v0 ?+ v1 q; ^4 F0 @! J+ x" U6 z% m
1        cat <&39 [* w$ V9 Z1 ^. W7 f

4 d4 q/ E7 o4 B& F
/ Y% n5 f2 r# n4 V6 j' V* f/ u$ A    后台关闭连接以后,cat命令会自动结束。
) A7 c  d: |) {. s* H$ O7 }" n
& v+ A1 U" H, \  J7 V9 i
/ R; F6 @2 v5 g9 [    如果是读取的二进制内容,可以用hexdump来查看。& c3 _6 D1 B/ ~; K0 }
5 D. F6 J9 g% I$ H* {  _& a! q
, n' F; Q5 [7 }5 V8 a
1        hexdump -C -n 31 <&38 x0 a+ Z8 W8 Q/ f8 n3 R
: N1 t. e4 _$ x& h0 x& K

" P1 G: B0 h2 m4 G9 P3 L4 x$ U    读出来效果如下:* i0 v" u- o( [/ F
: X4 T& O6 t. N7 G. ^
   
4 x7 R; G. o6 H" Q, W, l4 N/ W9 e% G$ B9 P4 X
    其中-n是指示hexdump读31个字节就结束。
7 D* a* l( n8 h5 y" m  v6 k
) \0 P, q! [9 p* G- I& }9 L    一个好的编程习惯,建立了连接要记得关闭。7 S# n  c  S* i; U" Z
    要关闭上面的socket连接可以这么写:
1 N6 Y3 a, \5 B1        exec 3>&- # 关闭写,不能再发请求 9 o5 r# ?4 v$ C/ A
2        exec 3<&- # 关闭读,不能再有返回     当然,你不关闭其实也不一定有啥大问题,bash脚本执行结束,该连接会自动被关闭。
0 V: s' z- w% ]' `! I
! r8 j1 N3 B1 o, ^$ ~    下面是我测试用的一个客户端:4 [4 V; s4 ?' {* d
1        #!/bin/sh( M8 w/ ]* r2 n: [; V: b
2        exec 3<>/dev/tcp/10.6.221.149/9865- J: L" z/ G) D
3        echo "<policy-file-request>" >&3
' w% n9 E3 Z) V6 B7 k! i" A4        cat <&3& ]% e3 p0 g$ E8 U4 N# j/ y
    瞧,这样的tcp客户端比C语言捣鼓出来的客户端代码少得不是一星半点啊。3 g  y2 U8 C9 X3 w: E
. J9 @% r$ U  E! U  x+ ?& l3 T8 z
    用bash操作udp也差不多的,如法炮制试试吧。
' e8 P5 H  m0 a6 ?& V* ?! B* v    当然,如果你很能捣鼓,还可以用bash写个服务端试试,捣鼓出来记得把代码分享给我看看。* r* [2 P( v, m# R, G

该用户从未签到

2#
发表于 2020-3-19 18:18 | 只看该作者
用bash做个tcp客户端
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-25 19:48 , Processed in 0.171875 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表