I've this Ruby server that uses a Unix Socket:
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
And I've this client in JavaScript that uses 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());
});
The problem is that at the first iteration of server loop, recv
receives the right string and the server replies to the client with the string data
. But at the second iteration recv
receives empty data and so a infinite loop begins... server continues to receive empty data and recv
does not block...
If I use a ruby client like this all works fine...
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
Your client closes the connection upon connecting, writing "hello world"
, and then receiving a response. Now your server is calling recv
on a socket that has been closed, which will return an empty string. Since you're looping to read on this socket indefinitely, it will never return control back to the outer loop to call accept
for the second client. The ruby version of your client works because it never closes the connection to the server.
Breaking out of your inner loop after receiving an empty string should get you what you want,
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
Another potential problem is that your server can only service a single connection to a single client, as the inner loop blocks any subsequent calls to accept
until the current connection ends.