You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用NetCat在Bash中搭建可处理请求并响应的TCP服务器?

使用NetCat搭建双向TCP服务器的解决方案

当然可以用NetCat实现你的需求!不过你当前的管道写法nc -kl 4444 | bash pipe.sh存在两个核心问题:

  • 普通管道是单向的:nc的输出(客户端请求)能传给脚本,但脚本的输出没法回流到nc,自然没法发给客户端
  • read命令异常:通常是因为NetCat的缓冲机制(默认可能是块缓冲),或者客户端发送的数据没有以换行符结尾,导致read无法正确识别输入边界

下面给你两种可行的实现方案,覆盖不同版本的NetCat:

方案1:使用NetCat的-e选项(推荐,适用于OpenBSD NetCat等支持该选项的版本)

很多主流版本的NetCat(比如openbsd-netcat)提供了-e参数,可以直接指定一个程序/脚本,让这个程序的标准输入、输出直接和NetCat的网络连接绑定,天然支持双向通信。

步骤1:编写处理脚本pipe.sh

#!/bin/bash
# 给客户端发送欢迎消息
echo "Hello from TCP Server! Type 'quit' to exit."

# 循环读取客户端发来的每一行数据
while read -r client_input; do
    # 处理请求:这里可以替换成你的业务逻辑
    echo "Server received: *$client_input*"
    
    # 特殊处理退出命令
    if [[ "$client_input" == "quit" ]]; then
        echo "Server closing connection..."
        exit 0
    fi
done

别忘了给脚本加执行权限:chmod +x pipe.sh

步骤2:启动服务器

nc -kl 4444 -e ./pipe.sh
  • -k:保持监听,处理完一个客户端后继续等待下一个
  • -l:监听模式
  • -e:指定连接建立后执行的脚本/程序

现在用telnet或者另一个nc客户端连接试试:nc localhost 4444,你会看到服务器的欢迎消息,发送的内容也会得到响应,输入quit会断开连接。

方案2:用命名管道(FIFO)实现双向通信(适用于不支持-e的NetCat版本)

如果你的NetCat版本(比如部分GNU NetCat)没有-e选项,可以用命名管道来模拟双向数据流。

步骤1:创建命名管道

mkfifo server_in server_out

这两个管道分别用来:

  • server_in:客户端→NetCat→脚本的输入通道
  • server_out:脚本→NetCat→客户端的输出通道

步骤2:修改处理脚本pipe.sh

让脚本从server_in读数据,把输出写到server_out:

#!/bin/bash
# 绑定脚本的标准输入到server_in,标准输出到server_out
exec < server_in > server_out

echo "Welcome to FIFO-based TCP Server!"
while read -r client_input; do
    echo "You sent: $client_input"
    if [[ "$client_input" == "quit" ]]; then
        echo "Goodbye!"
        # 退出后清理管道(可选)
        rm server_in server_out
        exit 0
    fi
done

同样给脚本加执行权限:chmod +x pipe.sh

步骤3:启动服务器

先启动NetCat,把它的输入输出和管道绑定,再启动脚本:

# 后台启动NetCat:从server_out读响应发给客户端,把客户端请求写到server_in
nc -kl 4444 < server_out > server_in &
# 启动处理脚本
./pipe.sh

解决read命令异常的小技巧

如果还是遇到read无法获取完整数据的情况,可以尝试:

  1. 关闭缓冲:用stdbuf命令强制NetCat和脚本使用无缓冲模式,确保数据实时传递:
    stdbuf -i0 -o0 nc -kl 4444 -e ./pipe.sh
    
    -i0:标准输入无缓冲,-o0:标准输出无缓冲
  2. 明确输入分隔符:如果客户端发送的数据没有换行符,可以用read -d ''读取所有数据(直到连接关闭),或者指定自定义分隔符,比如read -d '#'(如果客户端用#作为结束标记)

内容的提问来源于stack exchange,提问作者anton1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:02:17