CentOS虚拟机中Ncat连接报bad file descriptor问题排查求助
首先得说,你操作里有个一眼就能看到的低级错误——端口号不匹配!终端1用ncat -l 12345监听的是12345端口,但终端2发起连接时敲的是ncat my_hostname 13245,连的是13245端口!这俩端口不一样,肯定连不上,先把终端2的命令改成echo "Random string to send" | ncat my_hostname 12345(用管道传字符串更靠谱),先修正这个基础问题试试。
如果改完端口还是报错,再按下面的步骤排查,都是不需要root权限就能做的:
无root权限下的排查步骤
1. 确认监听是否真的生效
没有root权限的话,ss -tulpn这种带进程信息的命令用不了,但可以用lsof -i :12345——如果是你自己的用户启动的ncat监听,lsof应该能显示出对应的进程条目。如果没显示,说明监听没成功,要么是端口被其他进程占了,要么是系统有规则限制。
2. 先测本地回环,排除网络/hostname问题
别先急着用hostname,直接用127.0.0.1测试本地连接:
- 终端1:
ncat -lv 12345(加-v是开启 verbose 模式,能看到连接细节) - 终端2:
echo "test message" | ncat -v 127.0.0.1 12345
如果本地回环能通,说明问题出在hostname解析或者外部网络规则;如果还是不通,那大概率是本地系统的限制。
3. 排查防火墙/SELinux的间接影响
CentOS默认开着firewalld和SELinux,虽然你没root改不了规则,但可以间接验证:
- 你用的12345是大于1024的非特权端口,普通用户本来就有权限监听,所以特权端口的问题可以排除。
- 换用系统自带的
nc(netcat)试试,命令和ncat几乎一样:nc -l 12345和echo "test" | nc 127.0.0.1 12345。如果nc能正常通信但ncat不行,那可能是ncat的版本bug或者配置问题。
4. 替代tcpflow的调试方案
tcpflow需要抓包权限,普通用户用不了,但可以靠ncat自身的调试信息定位问题:
- 不管是监听还是连接,都加上
-vv(更详细的verbose模式),比如终端1用ncat -lvv 12345,终端2用ncat -vv my_hostname 12345。从输出里能看到是连接被拒绝,还是连接建立后立刻断开,这能帮你缩小问题范围。
5. 检查Ncat版本差异
Cygwin和CentOS上的Ncat版本可能不一样,用ncat --version分别看两边的版本。如果CentOS上的版本太老,你可以自己编译一个最新版的Ncat到用户目录下(不需要root,编译时指定./configure --prefix=$HOME/local,然后make && make install,之后用$HOME/local/bin/ncat调用就行)。
最后总结
先把端口号不匹配的问题修正,这是最容易忽略的点。如果改完还是不行,按照上面的步骤一步步排查,重点靠verbose输出找线索,对比nc的表现来区分是工具问题还是系统规则问题。
内容的提问来源于stack exchange,提问作者Bryce

