我正在尝试编写一个简单的bash脚本,该脚本正在侦听端口并使用简单的HTTP响应进行响应。我的具体问题是我不确定端口是否可用,如果绑定失败,我会回到下一个端口,直到绑定成功。
到目前为止,实现这一目标的最简单方法是:
for (( i=$PORT_BASE; i < $(($PORT_BASE+$PORT_RANGE)); i++ ))
do
if [ $DEBUG -eq 1 ] ; then
echo trying to bind on $i
fi
/usr/bin/faucet $i --out --daemon echo test 2>/dev/null
if [ $? -eq 0 ] ; then #success?
port=$i
if [ $DEBUG -eq 1 ] ; then
echo "bound on port $port"
fi
break
fi
done
我在netpipes Ubuntu软件包中使用faucet
。
问题在于,如果我只是在输出中打印“test”,curl
就会抱怨非标准的HTTP响应(错误代码18)。这是公平的,因为我不打印HTTP兼容的响应。
如果我将echo test
替换为echo -ne "HTTP/1.0 200 OK\r\n\r\ntest"
,curl仍抱怨:
user@server:$ faucet 10020 --out --daemon echo -ne "HTTP/1.0 200 OK\r\n\r\ntest"
...
user@client:$ curl ip.of.the.server:10020
curl: (56) Failure when receiving data from the peer
我认为问题在于faucet
如何打印响应和处理连接。例如,如果我在netcat
中执行服务器端,则curl工作正常:
user@server:$ echo -ne "HTTP/1.0 200 OK\r\n\r\ntest\r\n" | nc -l 10020
...
user@client:$ curl ip.of.the.server:10020
test
user@client:$
我非常乐意在主脚本中用faucet
替换netcat
,但问题是我想生成独立的服务器进程,以便能够从同一个基本shell运行客户端。 faucet
有一个非常方便的--daemon
参数,因为它分配给后台,我可以使用$?
(退出状态代码)来检查绑定是否成功。如果我出于类似的目的使用netcat
,我将不得不使用&
进行分叉,而$?
将不起作用。
是否有人知道为什么faucet
在这种特定情况下没有正确响应和/或可以建议解决此问题。我既没有和faucet
也没有netcat
结婚,但是希望使用bash或它的实用程序来实现解决方案(而不是用另一种脚本语言编写内容,比如Perl或Python)。 / p>
答案 0 :(得分:4)
faucet 10020 --out --daemon \
echo -ne "HTTP/1.0 200 OK\r\nContent-Length: 4\r\n\r\ntest"
工作正常。问题似乎是echo
不知道如何正确shutdown
套接字,而只使用close
而curl
对于获得-1(无序)感到不满意关闭)而不是来自recvfrom
的0(有序关闭)。
尝试socat
在孩子完成后继续清理。
socat tcp-l:10020,fork,reuseaddr \
exec:'echo -ne "HTTP/1.0 200 OK\r\n\r\ntest"'
答案 1 :(得分:2)
也许看看Richard Stevens的“袜子”节目。它有:
-F fork after connection accepted (TCP concurrent server)
http://www.icir.org/christian/sock.html
使用Bash你也可以使用:
echo $'HTTP/1.0 200 OK\r\n\r\ntest\r\n'
答案 2 :(得分:1)
你真的需要使用HTTP协议,还是只是为了讨好卷曲?如果是后者,只需合并
faucet $port --out --daemon echo test
与
hose $server $port --in cat
答案 3 :(得分:1)
如何使用DJB ucspi-tcp包中名为tcpserver的程序。
http://lserinol.blogspot.com/2008/12/simple-tcp-server-with-djb-tcpserver.html
netcat或nc的高级替代方案是ncat(nmap的一部分)。