我使用的是使用Unix Socket的Ruby服务器:
require 'socket'
server = UNIXServer.new('/tmp/ciccio.sock')
loop do
sock = server.accept
loop do
begin
data = sock.recv(1024)
data = "DO SOMETHING -> #{data}"
sock.write(data)
sock.flush
rescue Errno::EPIPE, Errno::ENOTCONN
break
end
end
end
我在JavaScript中的这个客户端使用了node.js net api:
Net = require('net');
var client = Net.connect({path: '/tmp/ciccio.sock'}, () => {
console.log('write data');
client.write('hello world!');
});
client.on('data', (data) => {
console.log(data.toString());
client.end();
});
client.on('end', () => {
console.log('end');
});
client.on('error', (error) => {
console.log(error.toString());
});
问题是在服务器循环的第一次迭代中,recv
收到正确的字符串,服务器使用字符串data
回复客户端。但是在第二次迭代recv
接收到空数据,因此开始无限循环...服务器继续接收空数据,而recv
不会阻止......
如果我使用像这样的ruby客户端一切正常......
require 'socket'
sock = UNIXSocket.new('/tmp/ciccio.sock')
loop do
sock.write('hello world!')
data = sock.recv(1024)
puts data
sleep(10)
end
sock.close
答案 0 :(得分:2)
您的客户端在连接,写"hello world"
,然后接收回复后关闭连接。现在,您的服务器在已关闭的套接字上调用recv
,这将返回一个空字符串。由于您循环读取此套接字无限期,它将永远不会将控制权返回到外部循环以为第二个客户端调用accept
。客户端的ruby版本可以工作,因为它永远不会关闭与服务器的连接。
收到空字符串后,打破内循环可以得到你想要的东西,
require 'socket'
server = UNIXServer.new('/tmp/ciccio.sock')
loop do
sock = server.accept
loop do
begin
data = sock.recv(1024)
break if data.empty?
data = "DO SOMETHING -> #{data}"
sock.write(data)
sock.flush
rescue Errno::EPIPE, Errno::ENOTCONN
break
end
end
end
另一个潜在的问题是您的服务器只能为单个客户端提供单个连接,因为内部循环阻止对accept
的任何后续调用,直到当前连接结束。