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

怎样用bash做个tcp客户端

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

/ H& N* T( |& t% K7 H1 V0 V& C日常做后台服务开发,总免不了要写测试客户端。但是tcp客户端写起来其实还是比较罗嗦的,各种错误返回,各种异常判断。。。。而我们通常并不是要写一个健壮的客户端,我们只是要一个能用的客户端来测试服务端是否正确。
/ x. U+ w) A# k' N    这里给大家介绍一个简单易用的方法:用bash操作socket!很酷,是不是?5 _  ]0 U4 {' w6 q* ^5 ~: Y) y
6 I8 x7 ^( d( W

/ X  m6 F0 E7 y2 g3 F7 r( @! }' m7 R    man bash,查找tcp关键字,可以看到这么一段内容:
- r- z# {& C1 c' r$ F1        /dev/tcp/host/port; c5 i' H0 p% q
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.9 y. m5 S# h. b7 h! ]8 X

6 V9 l0 `' H# {3 e, p    把其中的host和port换成我们要连接的IP和端口,就可以用来建立tcp连接了。如下:
, J8 X: {7 p: Y2 k
8 R0 U# D+ h7 d9 `1        exec 3<>/dev/tcp/10.6.221.149/9865
8 |3 T6 M( Q9 L9 b9 ?7 E: Y  _* ?3 d! r0 m) l

2 I9 ]+ q$ d, U6 b8 n    上面就建立了一个到10.6.221.149:9865的可读可写的socket连接。
# Q* F, b9 x9 [; V" ~    其中3就是指定的连接后的socket fd,由于0、1、2分别被stdin、stdout、stderr占用,所以可用fd最小从3开始。1 @/ V# t; X/ h8 U! a
    ip换成域名其实也是支持的,比如5 ^+ x! Y( q5 [4 K  }

3 G) h2 w+ |% x' [7 c1        exec 3<>/dev/tcp/www.xx.com/9865     注意"<>"前后不要空格,否则会出错。( [) z9 b2 R7 j& T" ^

6 z* @' Q1 N5 ^* [5 i- W, C    发送请求其实很简单,就跟往文件里写数据一样。例如
! d0 I: \& i8 J; q& e/ L" H+ S+ c. v. ]! [
1        exec "hello world." >&3
4 E7 R; O! J* J  `6 w
2 x% r+ p, W8 ^& {" a! Z- ^* n0 P9 V$ M' Q5 f
    如果要发HTTP请求,那可以这样:! P$ M: V& P8 A8 K: Z7 w

5 k! {( C( b' o! {( @6 K6 J1        echo -e "GET /crossdomain.xml HTTP/1.1\r\nHost:www.xx.com\r\n\r\n" >&3: v* R$ [# s" H( j, @
, e2 c, Y2 \, W8 Y! T" i/ j# v4 K

; h" U( @7 H! Y0 a     二进制请求可以这样发:; t% N6 Z) e) N0 D

" ~( `" Z; A# O0 h1        cat bin_data >&3! D1 ]3 y5 V9 X; L# p
1 R* k5 |: e- M5 S/ l, G" }

; T4 R, p  S" ^$ X* j9 D    其中bin_data是已经写好的二进制包数据文件。
' V' w- a# Z( E$ Q4 P+ q ) q) O8 V' \$ w0 [, X0 |
   读取服务器响应跟读文件差不多,可以这样写:
6 U. P' d' K& d# _( U. G4 q; t/ x) B0 T6 x
3 ^# e# g' Y- t" t# {4 q
1        cat <&3
6 B+ A: ?2 n; {
' e& b/ t' z# s- |" Y
- s7 g* d! _' E. h5 c+ g2 p    后台关闭连接以后,cat命令会自动结束。
+ q3 |# j8 [% S
0 E3 y% z9 Y1 f, p$ x9 Z4 A/ s
* l) r) {; ?5 ^/ Z+ z# `% o( ]# l0 B    如果是读取的二进制内容,可以用hexdump来查看。7 `( C5 o9 K. ~) S2 _# V4 h
5 y, U. ?* q8 k/ g. m

# a. E9 \+ ]. f$ K. I1        hexdump -C -n 31 <&3
* P+ d7 S3 @( v. M) k$ T' Y
1 N2 g1 r1 E% e. h& r. a9 J) F$ p
$ n0 D- J5 `! _# {9 S( F    读出来效果如下:2 I. i. Q, \7 r! A: [+ v; |& ?
3 e$ ^* U# m+ y( s& s/ Q/ E4 ?
   
' Z4 F7 c8 T$ r: P% A
. v5 j, W! c3 ?# B    其中-n是指示hexdump读31个字节就结束。# W4 g+ l8 w- |0 h
- x( ]9 s) k) o
    一个好的编程习惯,建立了连接要记得关闭。
& s! D6 k9 g6 ?$ d    要关闭上面的socket连接可以这么写:
9 j( B) j+ \! j% l/ g  O1 Z4 ]8 p1        exec 3>&- # 关闭写,不能再发请求
, m3 F  I  _2 L" A2        exec 3<&- # 关闭读,不能再有返回     当然,你不关闭其实也不一定有啥大问题,bash脚本执行结束,该连接会自动被关闭。
) K  x8 U" g6 z7 @1 [/ x+ i
, A0 I: s0 @% S! z( W    下面是我测试用的一个客户端:
/ Q- U4 ]' J  C! l# p( `1        #!/bin/sh
5 }# `$ s9 B& a% {% ~2        exec 3<>/dev/tcp/10.6.221.149/9865
1 `2 F5 D  I" P- O3        echo "<policy-file-request>" >&3% K8 `) q3 ?' k% `9 _  P
4        cat <&37 G+ }6 h( l: K
    瞧,这样的tcp客户端比C语言捣鼓出来的客户端代码少得不是一星半点啊。& v8 C0 _. A6 _8 p7 E
: {/ R( F; a7 u) w. c5 @
    用bash操作udp也差不多的,如法炮制试试吧。
# l$ w+ E, z! ?- c& b    当然,如果你很能捣鼓,还可以用bash写个服务端试试,捣鼓出来记得把代码分享给我看看。
8 R5 Q# f6 v% D% y" V" l+ ^7 F

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-25 17:36 , Processed in 0.156250 second(s), 27 queries , Gzip On.

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

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

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