TCL原生socket客户端连接Node.js Socket.IO服务端失败问题咨询
问题根因
你当前使用的Node.js服务端是Socket.IO上层协议服务,而非原生TCP Socket服务,TCL侧使用的是标准TCP套接字,两者协议不匹配导致无法完成应用层交互。
问题拆解
- TCP底层连接实际已经建立成功:TCL运行输出中可以正常获取对端套接字信息、
-error返回为空,说明3500端口监听正常,TCP三次握手已完成,没有网络/端口连通性问题。 - Socket.IO协议要求未满足:Socket.IO是基于WebSocket/HTTP长轮询封装的上层协议,TCP连接建立后需要客户端先发送符合Socket.IO规范的握手请求,服务端才会触发
connection事件回调。你当前TCL侧仅建立了TCP连接未发送任何握手数据,服务端会直接忽略该连接,不会返回任何响应,TCL的read命令默认需要读到EOF才会返回,因此会一直阻塞直到2分钟超时断开。 - Node.js CORS配置错误:你当前配置的origin为
http://localhost:3500,TCL客户端为TCP连接没有HTTP origin字段,即使发送握手请求也会被CORS拦截。
解决方案
方案1:Node.js改为原生TCP服务,匹配TCL的TCP套接字(实现成本最低)
Node.js服务端代码修改为:
const net = require('net'); // 创建原生TCP服务 const server = net.createServer((socket) => { console.log('Socket connected'); // 返回数据末尾加换行,适配TCL行读取逻辑 socket.write('Connected\r\n'); // 主动结束连接,触发TCL的read返回 socket.end(); }); server.listen(3500, '127.0.0.1', () => { console.log('TCP server listening on 127.0.0.1:3500'); });
TCL客户端可优化为行读取,避免阻塞:
set serverChannel [socket 127.0.0.1 3500] # 配置为行缓冲模式,读到换行就返回 fconfigure $serverChannel -buffering line puts [gets $serverChannel] close $serverChannel
方案2:TCL侧实现Socket.IO客户端逻辑,匹配现有Node.js服务
先修改Node.js的CORS配置放行请求:
const socket = new Server({ cors: { // 测试阶段可先放行所有来源,生产环境再配置指定origin origin: "*", credentials: true, }, allowEIO3: true, transports: ['websocket', 'polling'], serveClient: true, }).listen(3500);
TCL侧补充Socket.IO握手请求逻辑:
set serverChannel [socket 127.0.0.1 3500] # 发送Socket.IO polling模式握手请求 puts $serverChannel "GET /socket.io/?EIO=4&transport=polling HTTP/1.1\r\nHost: localhost:3500\r\nConnection: keep-alive\r\n\r\n" flush $serverChannel # 读取握手返回结果 puts [read $serverChannel] close $serverChannel
内容的提问来源于stack exchange,提问作者Perumal Samy S
相关产品推荐
相关产品推荐

