以下是一个实现客户端对 Shell HTTP 服务发起 POST
请求并传入 JSON 参数的完整示例。Shell 服务会解析收到的 JSON 数据,根据内容执行操作。
服务端脚本:http_server.sh
以下脚本使用 netcat (nc)
来监听 HTTP 请求,并通过 jq
工具解析 JSON 数据。
脚本内容:
#!/bin/bash
PORT=8080
echo "HTTP Server started on port $PORT..."
while true; do
{
# 读取请求行
read request_line
echo "Request: $request_line"
# 读取请求头,直到读取到空行(标志头部结束)
content_length=0
while read header && [[ "$header" != $'\r' ]]; do
echo "$header"
# 获取Content-Length值
if [[ "$header" == Content-Length:* ]]; then
content_length=$(echo $header | awk '{print $2}' | tr -d $'\r')
fi
done
# 读取请求体
if [[ $content_length -gt 0 ]]; then
read -n $content_length body
echo "Received Body: $body"
# 解析JSON并判断内容
command=$(echo "$body" | jq -r '.command')
echo "Command: $command"
# 根据JSON中的command字段执行不同操作
case $command in
"start")
response="Starting the service..."
;;
"stop")
response="Stopping the service..."
;;
*)
response="Unknown command: $command"
;;
esac
# 返回HTTP响应
echo -e "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n$response"
else
# 未提供JSON时返回错误
echo -e "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\n\r\nNo body received"
fi
} | nc -l -p $PORT -q 1 # 使用 netcat 监听端口
done
客户端:发送 POST 请求
客户端可以使用 curl
发送 POST
请求,并携带 JSON 数据。
客户端请求示例
# 发送启动命令
curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d '{"command": "start"}'
# 发送停止命令
curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d '{"command": "stop"}'
# 发送未知命令
curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d '{"command": "restart"}'
# 未提供JSON数据
curl -X POST http://localhost:8080
完整运行过程示例
-
启动服务:
$ ./http_server.sh HTTP Server started on port 8080...
-
客户端发起请求:
$ curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d '{"command": "start"}' Starting the service...
-
服务端日志输出:
Request: POST / HTTP/1.1 Content-Type: application/json Content-Length: 22 Received Body: {"command": "start"} Command: start
-
发送其他命令:
$ curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d '{"command": "stop"}' Stopping the service... $ curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d '{"command": "restart"}' Unknown command: restart
注意事项
-
依赖工具:
-
确保系统安装了
jq
(用于解析 JSON 数据),可以通过以下命令安装:sudo apt install jq # Ubuntu/Debian sudo yum install jq # CentOS/Red Hat
-
确保系统安装了
netcat (nc)
。
-
-
安全性:
- 此实现适合测试或开发环境,不建议直接用于生产环境。
- 生产环境建议使用更成熟的解决方案(如 Python Flask 或 Node.js)。
-
扩展功能:
- 可以在
case
中增加更多命令的处理逻辑。 - 可以验证 JSON 数据的格式,确保字段完整性。
- 可以在
这套脚本适合演示简单的 HTTP 服务和 JSON 数据交互,非常适合学习和快速搭建原型。
nc
命令详解
nc
是 Netcat 的命令行工具,常用于网络调试、监听端口、传输数据等。以下是命令中 nc -l -p $PORT -q 1
的含义:
选项解释
-
-l
- 启用监听模式,使
nc
在指定端口上等待连接。 - 没有这个选项时,
nc
作为客户端发起连接。
- 启用监听模式,使
-
-p $PORT
- 指定监听的端口号(这里用变量
$PORT
表示)。 - 例如,
-p 8080
表示监听 8080 端口。
- 指定监听的端口号(这里用变量
-
-q 1
- 在最后一次传输完成后等待 1 秒,然后关闭连接。
- 如果没有设置
-q
,nc
在交互完成后可能不会立即关闭连接。
nc
常用参数
通用选项
-
-v
- 启用详细模式,打印更多调试信息(如连接状态、错误等)。
- 示例:
nc -v 127.0.0.1 8080
-
-z
- 零 I/O 模式,用于扫描端口,不发送或接收数据。
- 常与
-v
搭配使用,测试远程主机的端口开放状态。 - 示例:
nc -zv 127.0.0.1 22
-
-u
- 使用 UDP 而非默认的 TCP 协议。
- 示例:
nc -u 127.0.0.1 12345
-
-n
- 禁用 DNS 解析,仅允许使用 IP 地址。
- 示例:
nc -n 192.168.1.1 80
-
-e <command>
- 执行一个命令,将该命令的输入和输出通过网络传输(远程 shell)。
- 示例:
nc -l -p 1234 -e /bin/bash
监听模式选项
-
-l
- 启用监听模式。
-
-p <port>
- 指定监听的端口。
-
-k
- 保持监听状态,即使已有连接也不会退出。
- 示例:
nc -l -p 8080 -k
-
-q <seconds>
- 在最后一次传输完成后,等待指定的秒数后关闭连接。
文件传输相关
-
-w <seconds>
- 设置连接超时时间(默认无限制)。
-
文件传输(发送文件):
# 在发送端: nc -l -p 1234 < file_to_send.txt # 在接收端: nc 127.0.0.1 1234 > received_file.txt
-
文件传输(目录打包):
# 发送端打包目录 tar -cvf - my_directory | nc -l -p 1234 # 接收端解压 nc 127.0.0.1 1234 | tar -xvf -
nc
的应用场景
-
HTTP 服务测试
模拟一个简单的 HTTP 服务器:
echo -e "HTTP/1.1 200 OK\r\n\r\nHello World" | nc -l -p 8080
-
端口扫描
检查远程主机开放的端口:
nc -zv 192.168.1.1 20-100
-
远程 Shell
在远程机器上打开一个 Shell:
# 服务端(监听远程 Shell 连接): nc -l -p 1234 -e /bin/bash # 客户端: nc 192.168.1.2 1234
-
调试网络连接
测试网络连通性:
nc -v 8.8.8.8 53
-
文件传输
通过网络快速传输文件:
# 发送端: nc -l -p 1234 < file.txt # 接收端: nc 192.168.1.2 1234 > received_file.txt
注意事项
- 使用
-e
启动远程 Shell 时需要小心,可能引发安全问题。 - 某些系统可能使用不同版本的 Netcat,如
OpenBSD nc
和GNU nc
,某些选项可能不支持。 - 对于需要长期运行的服务,推荐使用
-k
持续监听。
通过 nc
,我们可以快速搭建原型服务,调试网络问题,甚至完成文件传输任务,是一个非常实用的网络工具。