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

怎样用bash做个tcp客户端

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

  \* g$ e; o- Y# Q, d$ W0 B日常做后台服务开发,总免不了要写测试客户端。但是tcp客户端写起来其实还是比较罗嗦的,各种错误返回,各种异常判断。。。。而我们通常并不是要写一个健壮的客户端,我们只是要一个能用的客户端来测试服务端是否正确。2 a$ ?  E. c: _% l
    这里给大家介绍一个简单易用的方法:用bash操作socket!很酷,是不是?
& {; H7 L9 v3 o7 U4 _4 q
  ^% i/ w" H1 f- E9 z : g4 @! C) H8 _0 q8 F
    man bash,查找tcp关键字,可以看到这么一段内容:2 v" x; j. n$ ]" b
1        /dev/tcp/host/port
# [& N8 i( k9 K! E  F2               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.
0 n5 t. n! [2 H6 p6 n
' [6 d& j6 v7 k# F) K    把其中的host和port换成我们要连接的IP和端口,就可以用来建立tcp连接了。如下:% X3 i5 h9 n$ V1 r; V

5 O) Q, {, T9 A) }' _% y1        exec 3<>/dev/tcp/10.6.221.149/9865
$ |9 |# d! V# Z9 ?
1 Z& Q+ e8 c# O/ C; H7 y4 q/ F
    上面就建立了一个到10.6.221.149:9865的可读可写的socket连接。+ K/ s1 H3 a  s. B  A, c
    其中3就是指定的连接后的socket fd,由于0、1、2分别被stdin、stdout、stderr占用,所以可用fd最小从3开始。2 b" S2 Z, k+ D. Y% ?# u8 k
    ip换成域名其实也是支持的,比如
8 G  F4 y; t+ |* t
3 J" D4 l; E) g3 N4 s1 a" j5 K1        exec 3<>/dev/tcp/www.xx.com/9865     注意"<>"前后不要空格,否则会出错。
2 d/ n1 g* A5 g$ E& s, B
% k/ d/ T6 I" W: M, M    发送请求其实很简单,就跟往文件里写数据一样。例如
2 i+ ~) \4 L7 K" J- Z
) }, O+ N6 _( D) {1        exec "hello world." >&3: E$ W. Q# t( o1 b% j, C$ G6 M
% S/ o0 s+ L3 v; f5 Z( b' o+ ?) v0 Y

; K" {% u* X" D* W    如果要发HTTP请求,那可以这样:, K4 r' K  M5 Z7 t9 m

2 a8 U; E4 w! \0 {; _2 Y1        echo -e "GET /crossdomain.xml HTTP/1.1\r\nHost:www.xx.com\r\n\r\n" >&3: s" r: ^' ]' t$ ~: V$ y/ T7 I

6 t' R' H/ T; k0 t4 L7 W' j- o9 y4 d! a! y0 }; P3 W8 `. @4 ~
     二进制请求可以这样发:
9 U; g0 {. K: [& c! M  p& t2 V7 h
" j, b! V) C9 {1 v1        cat bin_data >&3
6 R1 M! [+ E, o9 p* k8 h
8 h3 L  |# L1 k" U% G
* F5 o6 o" }4 f2 ^. q7 Z    其中bin_data是已经写好的二进制包数据文件。7 {, E9 }; ]# {7 L( B8 o8 F- {

# x( M+ p$ o- I' |9 E   读取服务器响应跟读文件差不多,可以这样写:  G8 ^7 _& i# }4 P; x
7 V: k+ a" h$ Y( F+ t

' x( v; K  P% W+ u7 T3 T1        cat <&30 U/ [; L7 |5 I5 S' P0 }+ D

+ A" z" y6 B* T4 N1 n7 e& E
! N% R+ a+ }9 {8 B  M! ^& D! x1 C    后台关闭连接以后,cat命令会自动结束。
: u+ L' O( e$ K# U( Y" F0 x: d6 v& U- z, p

) F  j* W* Q6 ^" J7 r    如果是读取的二进制内容,可以用hexdump来查看。+ V: |: k* K+ I2 z
; @* e6 V9 u$ w7 M: g5 t+ r% J

. r+ o8 u; \- f/ m& |( R( C2 V1        hexdump -C -n 31 <&3
( y# ]1 W+ ?/ e: J/ k! E: T; P! v% K1 F: E9 C

, `8 W4 V5 _  w7 A5 @3 L, ~6 Z    读出来效果如下:/ d8 [/ @: G& ]. q/ t

, h, z5 a0 e! x" `, \   
' `7 F, g; U- u. N0 F" Z, i; I3 n/ v
2 `. N5 @/ b( o  [  c0 z. I    其中-n是指示hexdump读31个字节就结束。$ O( e4 P+ i3 ^, H: ]

& O' U0 j. B3 e, t- c    一个好的编程习惯,建立了连接要记得关闭。
: x' ?! {% i( p! ?1 _- U    要关闭上面的socket连接可以这么写:
% V+ D; M9 e, B4 v1        exec 3>&- # 关闭写,不能再发请求 " z& ]0 u( S0 `/ B; T3 c% N
2        exec 3<&- # 关闭读,不能再有返回     当然,你不关闭其实也不一定有啥大问题,bash脚本执行结束,该连接会自动被关闭。
  W& f9 V  w& R6 L6 D) W+ e" p: X, d  A1 O) V) o% c
    下面是我测试用的一个客户端:
& t& Z& E, E9 Z) C1        #!/bin/sh
. p; R4 J2 d3 L; n+ t2        exec 3<>/dev/tcp/10.6.221.149/9865
7 P# V( P' j/ x% m" _: q* j) ?( s/ g3        echo "<policy-file-request>" >&36 t) @- `' ^( z/ ?% [
4        cat <&3
7 O, W. d. E1 A/ h    瞧,这样的tcp客户端比C语言捣鼓出来的客户端代码少得不是一星半点啊。
6 a/ r9 k, t' p# t
" e2 |6 V5 L+ K3 u    用bash操作udp也差不多的,如法炮制试试吧。/ l5 |8 Q( O1 L6 _4 s8 y0 o
    当然,如果你很能捣鼓,还可以用bash写个服务端试试,捣鼓出来记得把代码分享给我看看。2 F9 D, w* E' B: J& X( Q: L

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-25 22:18 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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