tcpserver php,tcp server in bash

我想通过nc+bash创建一个tcp server, nc负责收发数据,bash负责处理数据,如何将nc和bash结合起来呢?

思路1: 通过nc的-c选项实现

思路2: 只要能想办法将nc的标准输入和标准输入重定向给bash脚本就行了; 我们常见的管道、进程替换都只能同时做重定向标准输入或标准输出的其中一件事情; 如:

nc -l -k -U /tmp/a.sock | while :; do read cmd echo $cmd done

1

nc-l-k-U/tmp/a.sock|while:;doreadcmdecho$cmddone

或:

while :; do read cmd echo $cmd done <

1

while:;doreadcmdecho$cmddone<

这两个都是单向的

思路3: 我们通常使用exec来做重定向,似乎也比较麻烦

思路4: bash中提供了一个coproc关键字,似乎用在这里再合适不过了

方法1:

handler.sh

while :; do

read cmd

echo $cmd

done

1

2

3

4

while:;do

readcmd

echo$cmd

done

server.sh

nc -l -k -U /tmp/a.sock -c handler.sh

1

nc-l-k-U/tmp/a.sock-chandler.sh

这里利用了nc 的-c选项;

注意:

这里的handler.sh 必须有可执行权限

handler.sh 必须在$PATH 里面,nc不参考当前目录

为了规避这两个问题,可以这样:

nc -l -k -U /tmp/a.sock -c 'bash handler.sh'

1

nc-l-k-U/tmp/a.sock-c'bash handler.sh'

这种情况下,对于每一个连接都会启动一个-c指定的进程来处理,类似于cgi的模式;如果client 离开的太快,handler.sh echo时会遇到pipe broken的错误,需要处理一下

需要仔细处理read ,避免client离开时,handler.sh还在无休止地循环,而且还占用 100% 的cpu

这里是通过两个文件来实现的,对于脚本程序来讲,如果一个文件能实现会方便很多;那么 nc 的 -c 选项能否接受一个bash 的function呢?直接写function显然是不行的,我们知道,环境变量是可以继承的,但是function 是不行的(参考: https://phpor.net/blog/post/9188),而且我们也不能把function赋值给一个变量; 或者可以这么实现:

if [[ $1 == "serve" ]]; then

while :; do

read cmd

echo $cmd

done

exit

fi

nc -l -k -U /tmp/a.sock -c "$0 serve"

1

2

3

4

5

6

7

8

9

if[[$1=="serve"]];then

while:;do

readcmd

echo$cmd

done

exit

fi

nc-l-k-U/tmp/a.sock-c"$0 serve"

但是,显得好不优雅; 而且,最大的问题就是,一不小心就可能成为fork炸弹💣

方法2:server.sh

#!/bin/bash

coproc handler {

while :; do

read cmd

echo $cmd

done

}

[ -e /tmp/a.sock ] && rm -fr /tmp/a.sock

nc -l -k -U /tmp/a.sock &${handler[1]}

1

2

3

4

5

6

7

8

9

10

#!/bin/bash

coprochandler{

while:;do

readcmd

echo$cmd

done

}

[-e/tmp/a.sock]&&rm-fr/tmp/a.sock

nc-l-k-U/tmp/a.sock&${handler[1]}

注意:

方法二的原理和方法一是不同的;这里的handler是一个常驻进程,不需要每次请求都fork一个handler,似乎更好一些,但是,handler无法区分不同的请求,client A可能接受到client B的请求的响应

问题:

这个server可以服务很多请求,但是无法实现服务完一个请求后主动断开

如何nc先退出了,handler如何判断

参考:

总结:

bash写个简版的东西还挺方便,写完善就不好弄了

方法一似乎更加合理一些

千万别用bash来实现tcpserver

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值