NodeJS:TCP套接字服务器只是第一次返回数据

我正在尝试在node.js中编写一个小的中继脚本,用于侦听本地套接字上的传入TCP连接,当它获取一个时,将stream量转发给第三方。 它还必须从该第三方获取任何返回的数据并将其发送回原始的本地套接字。 我已经尝试了像http://delog.wordpress.com/2011/07/19/a-tcp-relay-mechanism-with-node-js/这样的代码,它确实工作,但它要求发件人是一个服务器正在监听一个套接字本身,而我的工具是用来处理任何试图创build一个出站TCP连接的程序。 不幸的是,我遇到的问题是,当客户端首次将数据发送到“路由器”程序,路由器将其转发到另一台服务器,然后从客户端返回数据时,一切都很好。 但是,当客户端程序结束或终止并尝试重新连接,我得到这个:

events.js:72 throw er; // Unhandled 'error' event ^ Error: This socket has been ended by the other party at Socket.writeAfterFIN [as write] (net.js:275:12) at Socket.<anonymous> (/root/tcp_loop.js:37:17) at Socket.emit (events.js:117:20) at Socket.<anonymous> (_stream_readable.js:748:14) at Socket.emit (events.js:92:17) at emitReadable_ (_stream_readable.js:410:10) at emitReadable (_stream_readable.js:406:5) at readableAddChunk (_stream_readable.js:168:9) at Socket.Readable.push (_stream_readable.js:130:10) at TCP.onread (net.js:528:21) 

我剔除了所有的逻辑,并将testing用例分解成一小部分代码:一台服务器既可以作为路由器(监听端口8124),也可以作为“远程”服务器(端口9999),尽pipe我的testing表明它没有什么不同天气远程服务器是在同一台机器上,在互联网上等这里是服务器代码:

 var net = require('net'), util = require('util') ; // The loop_server simulates a remote service. // The error occurs whether using it here, or actually forwarding // the data to a remote host. var loop_server = net.createServer(function(loop) { console.log("Loop server connected"); loop.on("end", function() { console.log("Loop server disconnected"); }); loop.on("data", function(data) { console.log("Loop got data: " + data); loop.write(data); }); }).listen(9999, function() { console.log("Loop server bound"); }); var remote_socket = net.connect(9999, function() { console.log("Remote connected"); var local_server = net.createServer(function(local_socket) { //'connection' listener console.log('Local server connected'); local_socket.on('end', function() { console.log('Local server disconnected'); // local_socket.destroy(); }); local_socket.on('data', function(ldata) { console.log("Local socket got data: " + ldata); remote_socket.write(ldata); }); remote_socket.on('data', function(rdata) { console.log("Remote socket got data: " + rdata); local_socket.write(rdata); }); local_socket.write('hello\r\n'); }).listen(8124, function() { //'listening' listener console.log('Local server bound'); }); }); // remote_socket 

失败的是local_socket.write(rdata);remote_socket.on('data', ...处理程序中,它在路由器第一次启动和客户端连接的情况下工作,但不会再次。

作为参考,这里是我一直在使用的小客户端应用程序的代码。 我用perl脚本,telnet等得到相同的结果:

 var net = require('net'); var client = new net.Socket(); client.connect(8124, function() { console.log('CONNECTED TO: localhost:8124'); client.write('Single text message from the client app'); }); client.on('data', function(data) { console.log('DATA: ' + data); }); client.on('close', function() { sconsole.log('Connection closed'); }); 

任何有识之士将不胜感激。 我觉得我必须在这里错过一些非常简单的东西…

更新:

下面的Nitzin的解决scheme是一个更好的方法来做到这一点,但在我下面的特定示例中,解决scheme是删除旧的remote_socket.on('data')侦听器,然后创build新的,如:

 var remote_socket = net.connect(9999, function() { console.log("Remote connected"); var local_server = net.createServer(function(local_socket) { //'connection' listener console.log('Local server connected'); remote_socket.removeAllListeners('data'); ... remote_socket.on('data', function(rdata) { console.log("Remote socket got data: " + rdata); local_socket.write(rdata); }); 

你不应该destroysockets。 它closures了套接字的两端。 你只应该.end()它,这将closures你的写作结束。

编辑

破坏套接字是不好的,就像我最初写的那样,但是你真正的问题是完全不同的:你得到你的代理服务器(你称之为“local”)和echo(你称之为“remote”)服务器: 代理服务器应该一个新的连接到回应服务器为每个新的连接代理服务器得到,而不是相反,因为你现在。

唯一的end()需要在客户端,让服务器知道你已经写完了。

这里是client.js

 var net = require('net'); var client = new net.Socket(); client.connect(8124, function() { console.log('CLIENT: CONNECTED: localhost:8124'); client.write('single text message from the client app'); client.end(); }); client.on('data', function(data) { console.log('CLIENT: GOT DATA: ' + data); }); client.on('close', function() { console.log('CLIENT: CONNECTION CLOSED'); }); 

这里是servers.js

 var net = require('net'), util = require('util'); net.createServer(function(conn) { console.log('ECHO_SERVER: CONN: new connection'); conn.on('end', function() { console.log('ECHO_SERVER: CONN: disconnected'); }); conn.on('data', function(data) { console.log('ECHO_SERVER: CONN: GOT DATA: ' + data); conn.write(data); }); }).listen(9999, function() { console.log('ECHO_SERVER STARTED'); }); net.createServer(function(conn) { console.log('PROXY_SERVER: CONN: new connection'); var remote = net.connect(9999, function() { console.log('PROXY_SERVER: CONNECTED TO ECHO_SERVER'); conn.on('end', function() { console.log('PROXY_SERVER: CONN: disconnected'); remote.end(); }); conn.on('data', function(data) { console.log('PROXY_SERVER: CONN: GOT DATA FOR ECHO_SERVER: ' + data); remote.write(data); }); remote.on('data', function(data) { console.log('PROXY_SERVER: CONN: GOT DATA FROM ECHO_SERVER: ' + data); conn.write(data); }); }); }).listen(8124, function() { console.log('PROXY_SERVER STARTED'); }); 

正如你所看到的,对于代理服务器的每个conn ,都有一个新的remote服务器进入echo服务器。