20834

basic Ruby TCP server demo fails on startup: `bind': Address already in use, Errno::EADDRINUSE

I am presenting a simple TCP server demo in Ruby. My first demo is using classical C-style bind-listen-accept-read-write-close methods. This code works well for the first time:

require 'socket'

class Server

  def start(bind: '127.0.0.1', port: nil, backlog: 1)

    Socket.new(:INET, :STREAM).tap do |sock|
      sock.bind Addrinfo.tcp bind, port
      sock.listen backlog

      # the codes of client connecting with it here is for reproducing the issue more easily
      c = Socket.new(:INET, :STREAM)
      c.connect Addrinfo.tcp '127.0.0.1', port

      client, client_addr = sock.accept
      puts "connected from #{client_addr.ip_address}:#{client_addr.ip_port}"

      client.puts "hi"

      client.close
      sock.close

    end
  end

end

Server.new.start(port: 23333)


However when I tried to run it again, I got an errors of EADDRINUSE:

`some-script.rb:8:in `bind': Address already in use - bind(2) for 127.0.0.1:23333 (Errno::EADDRINUSE)`

After about 30 seconds, I can start the script successfully again. Not sure if this is done by the kernel.

Dosn't Socket#close fully close the socket and kernel close the TCP connection?

I tried it on both Mac OS 10.11.1 and Ubuntu 14.04 and got the same result. After reading ruby's source code (socket.c) I still can't figure it out.

Any advice?

Answer1:

You can work around this by calling sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true) before the call to sock.bind().

Recommend

  • How to UnCommit to a PBI [closed]
  • mono/linux socket denied?
  • Is there a TFS query macro for the current iteration?
  • Monitor transport,network and link layer buffers/queue (loaded, empty, full and drop) in Linux
  • How to send an std::vector of unsigned char over an UDP socket using boost asio?
  • Getting socket.io namespace from anywhere in the project
  • How to read data from socket connection - android
  • Cannot send user message with Spring Websocket
  • Issue when joining serf nodes located in different Docker containers
  • Getting zero results in search using elastic4s
  • Setting src to Base64-encoded image with Javascript is failing
  • NSMutableArray instance used in a block
  • XOR with Neural Networks (Matlab)
  • Error in making a socket connection
  • pymongo replication secondary readreference not work
  • CORS with socket.io
  • Prevent Tomcat from caching request during starup
  • Access Android Market through SSH tunnel
  • Grails calculated field in SQL
  • How to run “Deployd” on port 80 instead of port 5000 in webserver.
  • Row Count Is Returning the incorrect number using RaptureXML
  • Resize panoramic image to fixed size
  • How to add date and time under each post in guestbook in google app engine
  • Obtain ObjectIdHex value from mgo query
  • Volusion's generic SQL folder, functionality
  • JSON with duplicate key names losing information when parsed
  • Return words with double consecutive letters
  • how to add data labels for bar graph in matlab
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • NSLayoutConstraint that would pin a view to the bottom edge of a superview
  • python regex in pyparsing
  • How do you join a server to an Active Directory (domain)?
  • coudnt use logback because of log4j
  • Java static initializers and reflection
  • Android Google Maps API OnLocationChanged only called once
  • Bitwise OR returns boolean when one of operands is nil
  • unknown Exception android
  • Observable and ngFor in Angular 2
  • Unable to use reactive element in my shiny app
  • How can I use threading to 'tick' a timer to be accessed by other threads?