使用nc搭建TCP服务器时无法输入执行命令问题求助
问题成因
你写的执行逻辑存在两个核心错误,导致无法输入、逻辑不生效:
- 命令执行顺序错误:你把
nc -l localhost 3000和后面的while循环写成了顺序执行的两行,shell会阻塞等待nc进程完全退出后,才会启动后面的while循环。nc运行时while逻辑根本没加载,自然不会对你的输入做任何响应。 - 数据流逻辑完全错误:nc本身是网络转发工具,不会自动把收到的网络数据传给本地shell逻辑执行,也不会把本地shell的输出自动发回网络连接。你单独运行
nc -l localhost 3000时,键盘输入的内容会直接发送给连上来的TCP客户端,收到的客户端数据会直接打印在当前终端,和你写的case判断逻辑没有任何数据通路。
另外不同发行版预装的nc实现存在差异(OpenBSD版nc、传统GNU nc参数和管道行为不完全一致),如果直接用管道拼接nc和shell逻辑,默认是单工通信,会出现发不出响应的问题。
解决方法
首先要通过命名管道(FIFO)给nc建立双向数据通路,把nc收到的网络数据传给shell逻辑处理,再把shell的处理结果传回nc发给客户端。
测试d/q/通配符逻辑的可运行版本
#!/bin/bash # 先清理残留的管道文件 rm -f test_pipe # 创建命名管道 mkfifo test_pipe # 启动nc监听,把管道内容作为nc的输入,nc收到的网络数据传给while循环处理 nc -l 127.0.0.1 3000 < test_pipe | while read -r cmd; do case $cmd in d) date > test_pipe ;; q) echo "exit" > test_pipe rm -f test_pipe exit 0 ;; *) echo 'What?' > test_pipe esac done
运行这个脚本后,新开一个终端执行nc localhost 3000,在新开的客户端终端里输入d、q或者其他内容,就能触发对应的分支逻辑。
支持ECHO/SET/GET三个功能的完整简易TCP服务器实现
预设存储上限为100个键值对,完全匹配提出的功能要求:
#!/bin/bash # 配置参数 LISTEN_PORT=3000 MAX_STORE_CAP=100 PIPE_FILE=server_pipe # 初始化存储结构、清理旧管道 declare -A KV_STORE rm -f $PIPE_FILE mkfifo $PIPE_FILE # 启动服务循环 nc -l 127.0.0.1 $LISTEN_PORT < $PIPE_FILE | while read -r raw_cmd; do # 匹配ECHO命令 if [[ $raw_cmd == ECHO\ * ]]; then echo "${raw_cmd#ECHO }" > $PIPE_FILE # 匹配SET命令(注意SET后带两个空格的规则) elif [[ $raw_cmd == SET\ \ * ]]; then kv_pair="${raw_cmd#SET }" key="${kv_pair%% *}" value="${kv_pair#* }" # 检查存储上限:新key且当前存储数已满则返回错误 if [[ -z ${KV_STORE[$key]} && ${#KV_STORE[@]} -ge $MAX_STORE_CAP ]]; then echo "!err" > $PIPE_FILE else KV_STORE[$key]="$value" echo "!200" > $PIPE_FILE fi # 匹配GET命令 elif [[ $raw_cmd == GET\ * ]]; then key="${raw_cmd#GET }" if [[ -n ${KV_STORE[$key]} ]]; then echo "${KV_STORE[$key]}" > $PIPE_FILE else echo "!error" > $PIPE_FILE fi # 未知命令统一返回错误 else echo "!invalid command" > $PIPE_FILE fi done # 退出时清理管道文件 rm -f $PIPE_FILE
测试注意:启动服务脚本后,不要在运行服务的终端直接输入命令,需要新开终端执行
nc localhost 3000建立连接,在客户端终端输入命令验证:
- 输入
ECHO 测试内容,服务端会返回对应测试内容- 输入
SET testkey testval,存储成功返回!200,存储数量达到100个上限后写入新key返回!err- 输入
GET testkey返回对应存储的testval,查询不存在的key返回!error
内容的提问来源于stack exchange,提问作者IshAsh
相关产品推荐
相关产品推荐

