带有Node.js客户端的Ruby UNIXServer

时间:2015-11-25 12:52:04

标签: ruby node.js sockets client-server unix-socket

我使用的是使用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

1 个答案:

答案 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的任何后续调用,直到当前连接结束。