TinyURL widget - shorten your URL's for free!

Enter a long URL to make tiny:

Thursday, October 15, 2015

Network socket configuration Linux in C



I have had the pleasure of configuring:

  • IP sockets for reading and writing
  • multi-cast IP sockets for reading and writing
  • broadcast IP sockets for reading and writing

in the span of about 4 weeks, intermittently.

Here is what I have learned:

There is a lot of confusion based on the server/ client mentality. Clients can read and write; and so can servers so this doesn't always fit.   Because people construct half-assed examples usually using only one type of interface it's not clear from these what the patterns are. For example, one source example uses the loopback address but the coder didn't realize this was a special version of the process and his code spat out errors when moved to a generic setup with 3 addresses.

Instead: think of it in terms of LOCAL address and FOREIGN address rather than client / server model.

You need to setup your local configuration first so you need SOURCE ADDRESS data.  When you go to interact on the internet (READ/ WRITE) you need the DESTINATION ADDRESS data.


Every IP transmission involves a DESTINATION and SOURCE IP address.  The context of which is which depending on if you are reading or writing and if that changes.  So there can be confusion as to which gets configured. And if you want a GROUP multicast you need 3 IP ADDRESSES. The last is the group you are joining.



When making a reading socket or writing socket you must bind it to the LOCAL (what they call the DESTINATION  address from the sending / server side)  IP Address of the machine you are on so the network interface recognizes it.  Of course, what if you have multiple interfaces and you don't know a priori which one to bind to? Simple: bind to IN_ADDRANY as a way to leave that to the network routing rules.  You need to bind or there is no network traffic to your socket as a reader.  You can get away with not binding writers if you decide to change the address on a packet by packet basis. But I would bind for a session in most cases, it also brings up problems with your code in configuration that may stop errors later. As a wiser older Unix programmer, I would rather bind to a session, fork and kill rather than reusing it...

When you begin to read from a specific FOREIGN (what they call the SOURCE address from the sending side  ) IP ADDRESS with a command like recvfrom() your command will block until data is ready. For a DATAGRAM it is mainly all or nothing so it won't return until the data packet is complete.  If you run your program and there is no data reading, it means you are not configured correctly.

When multi-casting, you need to not only bind to the local address, you need to set the group address and the local address in a group request and then JOIN the multicast group.  There is no LEAVE message so your host can quit anytime.

When you are reading broadcast packets, you don't have to set permission to broadcast, just configure, bind, and recvfrom().

When you are writing broadcast packets on Linux, you MUST setsockopt to BROADCAST something like:
      int broadcast = 1;
      z = setsockopt(s, 
                     SOL_SOCKET, 
                     SO_BROADCAST, 
                     &so_broadcast, 
                     sizeof( so_broadcast) );

Otherwise, the packets won't be sent.

In all cases with a modern kernel, I have had no problems with the networking packets arriving timely. It is the configuration of the code that has taken the longest.

No comments:

Post a Comment