lib/ionian/socket.rb in ionian-0.4.1 vs lib/ionian/socket.rb in ionian-0.5.0

- old
+ new

@@ -4,26 +4,47 @@ # A convenient wrapper for TCP, UDP, and Unix sockets. class Socket # Args: - # host: IP or hostname to connect to. - # port: Connection's port number. Default is 23. Unused by :unix protocol. - # protocol: Type of socket to create. :tcp, :udp, :unix. Default is :tcp. + # host: IP or hostname to connect to. + # port: Connection's port number. Default is 23. Unused by :unix protocol. + # protocol: Type of socket to create. :tcp, :udp, :unix. Default is :tcp. + # :udp will be automatically selected for addresses in the multicast range. # persistent: The socket remains open after data is sent if this is true. # The socket closes after data is sent and a packet is received # if this is false. Default is true. + # bind_port: Local UDP port to bind to for receiving data, if different than + # the remote port being connected to. + # reuse_addr: Set true to enable the SO_REUSEADDR flag. Allows local address reuse. + # no_delay: Set true to enable the TCP_NODELAY flag. Disables Nagle algorithm. + # cork: Set true to enable the TCP_CORK flag. Buffers multiple writes + # into one segment. # expression: Overrides the #read_match regular expression for received data. def initialize(**kwargs) @socket = nil + # TODO: Should be able to parse the port out of host. + # :port should override this parsed value. + @host = kwargs.fetch :host - @port = kwargs.fetch :port, 23 - @protocol = kwargs.fetch :protocol, :tcp + @port = kwargs.fetch :port, 23 + @bind_port = kwargs.fetch :bind_port, @port + + # Automatically select UDP for the multicast range. Otherwise default to TCP. + default_protocol = :tcp + default_protocol = :udp if Ionian::Extension::Socket.multicast? @host + default_protocol = :unix if @host.start_with? '/' + + @protocol = kwargs.fetch :protocol, default_protocol @persistent = kwargs.fetch :persistent, true @expression = kwargs.fetch :expression, nil + @reuse_addr = kwargs.fetch :reuse_addr, false + @no_delay = kwargs.fetch :no_delay, false + @cork = kwargs.fetch :cork, false + create_socket if @persistent end # Returns a symbol of the type of protocol this socket uses: # :tcp, :udp, :unix @@ -121,18 +142,33 @@ @socket.close if @socket and not @socket.closed? case @protocol when :tcp @socket = ::TCPSocket.new @host, @port + @socket.extend Ionian::Extension::Socket + @socket.no_delay = true if @no_delay + @socket.cork = true if @cork + when :udp @socket = ::UDPSocket.new - @socket.bind '', @port + @socket.extend Ionian::Extension::Socket + + @socket.reuse_addr = true if + @reuse_addr or Ionian::Extension::Socket.multicast? @host + + @socket.bind ::Socket::INADDR_ANY, @bind_port @socket.connect @host, @port + + @socket.ip_add_membership if Ionian::Extension::Socket.multicast? @host + when :unix @socket = ::UNIXSocket.new @host + @socket.extend Ionian::Extension::Socket end - @socket.extend Ionian::Extension::Socket + # TODO: Implement SO_LINGER flag for non-persistent sockets; + # especially send-and-forget. + @socket.expression = @expression if @expression initialize_socket_methods end \ No newline at end of file