# Socket

The Socket family of classes is the means that Ruby's standard library uses by default to communicate using networks.
The typical use flow is to create a socket
Then read to and write from a.
Now, if you try and read from a socket, it will typically block until some data comes in
You can avoid this blocking call by first checking if there is impending data, to do this you use the select call.
At this point if a has any incoming data, readable will be an array like [a], otherwise it will be nil. if a is writable, then writable will be an array like [a]
error is typically never used, though it might be useful in certain instances.
The select method is really just a wrapper for the underlying select c call for whatever operating system you're on, though in general the semantics should be the same cross platform.
Another way to read without blocking is to call a.recv_nonblock(1024), which will raise an exception if nothing is available.

### Example

Here's an example:

## Echo Client/Server

server.rb (run this first)
client.rb
Output server:
Output client:

## How to tell when a socket closes

If BasicSocket#recv (available to all sockets) returns "" that means that the socket has been closed from the other side. The call to recv raising something like "ECONNRESET" means that the socket was closed, but ungracefully, from the other side.

## Keeping a connection alive over time when there is no traffic being sent

It's common knowledge that TCP sockets stay active until they're closed by one side or the other. But while they're open but not any transmitting data, it's possible that the connection becomes invalid. For example if the other side (the remote side) has gone away, or been rebooted or what not. It's also possible that intermediate NAT's will timed out your connection after awhile unused, thus also rendering the connection invalid. The real problem with this is that if you don't send any data, and the connection is invalid, you will only discover this fact *after* you send data, later. The notification can be thus delayed.
The fix to this problem is to either, every so often, send a ping message or your own, or to set the TCP_SOCKET keepalive option, like
Note that this option works for sockets that have already been opened. Also note from here that it appears to only send a ping every two hours or so.
If you have a timeout on read data (like you require them to send you something within x seconds or you will consider them dead), then you can track the last input using Time.now, then use the select command (with a reasonable timeout). Then, after each select, process the results, then iterate over your connections to see if old ones have become invalid because they haven't sent you data for a long time.

## setting socket options

Note also that many options must be set before a socket is opened.
here is some code demonstrating how to set one.

## Flushing

By default sockets are typically created with the NAGL optimization option turned on, which means that there is a tiny delay before sending data after a write, which is so that if more small data is sent before the packet leaves, it can combine them into one packet.
This can cause extra latency for the last of a set of packets. But can result in a small speedup by avoiding the overhead of multiple packets.
To get around the latency for the end packet, you'll either want to call #flush on your sockets immediately after writing (preferably leave NAGL on, write a lot, then call #flush), or set the socket option to disable NAGL. See Nagle's algorithm for more information.

## UDP Socket Example

server (run this first):
client:

## UDP Broadcast Example

See

## Multicast Example
### Linux

See.

### Windows

See
Also note "in Windows the setsockopt call has to come after the bind call." from http://www.ruby-forum.com/topic/133208

## Alternatives

Other ways, such as using the eventmachine gem, also provide Socketed programming, with some benefits like better functionality with many sockets (and some drawbacks). The Rev gem is similar, though written mostly in Ruby, not C.

### Fibered

You can use sockets with fibers (i.e. single threaded, but multiple connection) by using 1.9 + revactor or neverblock gem.

## External Links

* www.tutorialspoint.com/ruby/ruby_socket_programming.htm a tutorial
* a tutorial.
* a tutorial
* ↑ http://betterlogic.com/roger/?p=1646
* ↑ http://onestepback.org/index.cgi/Tech/Ruby/MulticastingInRuby.red
* ↑ http://www.ruby-forum.com/topic/200353