Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: How to detect when one side of a socket has been closed

Tags:

ruby

sockets

How can I detect that a socket is half-open? The case I'm dealing with is when the other side of a socket has sent a FIN and the Ruby app has ACKed that FIN. Is there a way for me to tell that the socket is in this condition?

Take, for example:

require 'socket'

s = TCPServer.new('0.0.0.0', 5010)

loop do
  c = s.accept

  until c.closed?
    p c.recv(1024)
  end
end

In this case, when I telnet into port 5010, I'll see all my input until I close the telnet session. At that point, it will print empty strings over and over as fast as it can.

like image 222
Alex Avatar asked Apr 30 '09 15:04

Alex


People also ask

How do you know if a socket has been closed?

The most obvious way to accomplish this is having that process call read on the socket for a connection and check whether read returns 0 (i.e. reads zero bytes from the socket), in which case we know that the connection has been closed.

How do I know if my TCP connection is closed?

periodically check the TCP connection status via client. status() - in case it is 0, close the connection. This works when the connection is closed correctly by client, however doesnt work when the connection is closed incorrectly (lost wifi - phone cant ask Photon first to close the connection).

What happens if socket is closed?

close() call shuts down the socket associated with the socket descriptor socket, and frees resources allocated to the socket. If socket refers to an open TCP connection, the connection is closed. If a stream socket is closed when there is input data queued, the TCP connection is reset rather than being cleanly closed.

How do I know if my socket is connected?

If you need to determine the current state of the connection, make a nonblocking, zero-byte Send call. If the call returns successfully or throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.

How do I read from a TCP socket in Ruby?

Ruby class TCPSocket provides open function to open such a socket. The TCPSocket.open (hosname, port ) opens a TCP connection to hostname on the port. Once you have a socket open, you can read from it like any IO object.

What are the different types of sockets in Ruby?

Ruby Socket 1 Network protocols. ... 2 Address families. ... 3 Ruby Socket.getnameinfo. ... 4 Socket.getifaddrs & Socket.ip_address_list. ... 5 Ruby UDP socket example. ... 6 Ruby TCP socket example. ... 7 Ruby Socket HTTP HEAD request. ... 8 Ruby Socket GET request. ... 9 Ruby client/server example. ... 10 Ruby socket simple web server. ...

What does it mean when a socket is not closed?

The socket is not closed when the block returns. So application should close it explicitly. This method calls the block sequentially. It means that the next connection is not accepted until the block returns. So concurrent mechanism, thread for example, should be used to service multiple clients at a time.

Is it safe to close a socket when the block returns?

The socket is not closed when the block returns. So application should close it. This method deletes the socket file pointed by path at first if the file is a socket file and it is owned by the user of the application. This is safe only if the directory of path is not changed by a malicious user.


1 Answers

You are using the blocking call recv, which will return nil when the other end closes. The socket won't be closed until you close it. Change

  until c.closed?
    p c.recv(1024)
  end

to

while (s = c.recv(1024)) && s > 0
   p s
end
c.close
like image 135
Rumbleweed Avatar answered Nov 07 '22 17:11

Rumbleweed