Simple tools for networking / objects in plain C Snapshot
sock.h
Go to the documentation of this file.
00001 #ifndef __SOCKSOCK_H_
00002 #define __SOCKSOCK_H_
00003 
00004 
00005 /**
00006   @defgroup SOCKET
00007   @brief a usable socket abstraction
00008 
00009   When you create a socket(2) then it is blocking by default.
00010   This means that you can't specify a timeout while using the socket - that makes it useless for any practical purpose.
00011 
00012   This abstraction creates a non blocking socket, and you can use it in a blocking manner from a thread, alas you can specify timeouts.
00013   This way you can have 'one thread per connection' in a way that allows you to  set timeouts for read, write and connect primitives.
00014 
00015   In a way this wrapper replace one set of utterly incomprehensible default behavior (the Berkley socket api) with another set of behaviour (which maybe makes more sense, maybe it doesn't - a matter of taste, as many things are with computers)
00016 
00017   Still, the Berkley socket interface is supposed to create the illusion, that one can do TCP networking without understanding the protocols. That is an illusion, and one simply has to read 'TCP IP Illustrated' by R. Stevens in order to correct it.
00018 
00019 * @{
00020 */
00021 typedef struct tagSOCKCTX {
00022 
00023   int verbose;
00024   int connected;
00025   int close_on_peer_close;
00026   int fd;
00027 
00028   void *addr; 
00029   int addr_size;
00030   
00031 } SOCKCTX;
00032 
00033 #ifndef LINGER_OPTION_VALUE
00034 #define LINGER_OPTION_VALUE 300
00035 #endif
00036 
00037 /**
00038   if flag is set then nagle algorithm is enabled - this is the opposite behaviour of normal sockets where nagle is enabled by default.
00039 
00040  The Nagle algorithm makes sense for high latency networks such as the internet; it does not make sense for low latency LAN networks. Here application performance is typically faster without the nagle algorithm. - this stuff therefore assumes
00041  that is more likely used in a local network.
00042  
00043  The Nagle algorithm http://en.wikipedia.org/wiki/Nagle%27s_algorithm tries to combine network writes into larger packets, If the application calls send then the data is not Immediately written out; instead it is gathered with the hope of accumulating data into larger packets, these packets are then sent on the Nagle algorithm's timer.
00044 
00045 */
00046 #define SOCKCTX_FLAGS_NAGLE_ON 2
00047 
00048 /**
00049   In 99% of all application protocols you will want to close the connection,
00050   once the peer closes it's side, and recv returns 0.
00051 
00052   Set this option if you do not want the socket closed, once the peer closes it's side of the connection, and recv returns 0;
00053 
00054   Setting this option means the following. Once the peer closes its connection, it is no longer able to
00055   send data over the connection, howeve the peer still expects to read outstanding data that will be send by the application,
00056   and the application will send this data after it has received the information that the peer closed its side.
00057 
00058   Also, if this options is set, then SO_LINGER option is enabled to the value of LINGER_OPTION_VALUE
00059   This means that when the socket is closed, and there is data that has to be written still, then close will block
00060   until the outstanding data has been acknowledged by the peer.
00061 */
00062 #define SOCKTCX_FLAGS_DONT_CLOSE_ON_PEER_CLOSE 4
00063 
00064 
00065 /**
00066 @brief creates a socket and sets some options
00067 @param ctx - pointer to socket object.
00068 @param verbose
00069 @param flags  - bitmask of SOCKTX_FLAGS_xxx values
00070 */
00071 int SOCK_init( SOCKCTX *ctx , int verbose, int flags);
00072 
00073 int SOCK_attach( SOCKCTX *ctx , int fd, int verbose, int flags);
00074 
00075 
00076 /**
00077 @brief creates a socket and sets some options
00078 @param ctx - pointer to socket object.
00079 @param verbose
00080 @param flags  - bitmask of SOCKTX_FLAGS_xxx values
00081 */
00082 int SOCK_init( SOCKCTX *ctx , int verbose, int flags);
00083 
00084 
00085 /**
00086  @brief set read and write buffer sizes; a value of -1 for buffer size is ignored.
00087  @param ctx - pointer to socket object.
00088  @param read_buffer_size
00089  @param write_buffer_size
00090  */
00091 int SOCK_send_buffer_sizes( SOCKCTX *ctx, int read_buffer_size, int write_buffer_size);
00092 
00093 /**
00094  @brief connects a sockets with timeout (in seconds)
00095  @param ctx - pointer to socket object.
00096  @param addr
00097  @param addr_size
00098  @param connect_timeout
00099  */
00100 int SOCK_connect( SOCKCTX *ctx, void *addr, int addr_size, int connect_timeout);
00101 
00102 /**
00103  @brief read some data from a socket with timeout (in seconds)
00104  @param ctx - pointer to socket object.
00105  @return either one of: -1 on error, 0 if socket has been closed, number of bytes read.
00106  */
00107 int SOCK_recv( SOCKCTX *ctx, void *msg, size_t length, int read_timeout );
00108 
00109 /**
00110  @brief read whe whole buffer from a socket with timeout (in seconds)
00111  @param ctx - pointer to socket object.
00112  @return either one of: -1 on error, 0 if socket has been closed during receiving buffer, length on success.
00113 */
00114 int SOCK_recv_all( SOCKCTX *ctx, void *msg, size_t length, int read_timeout );
00115 
00116 /**
00117  @brief write whe whole buffer from a socket with timeout (in seconds)
00118  @param ctx - pointer to socket object.
00119  */
00120 int SOCK_send( SOCKCTX *ctx, void *msg, size_t length, int write_timeout );
00121 
00122 /**
00123  @brief close the 
00124  @param ctx - pointer to socket object.
00125 socket
00126  */
00127 int SOCK_close( SOCKCTX *ctx );
00128 
00129 /**
00130 @brief ungraceful connection termination.
00131 
00132 This function avoids TIME_WAIT when initiating closing of connection.
00133 
00134 TIME_WAIT occurs, when the socket has been shut down properly; the application has sent FIN to the peer, and received an ACK for this message; the application has now sent the final last ACK to the peer; the connection is now in TIME_WAIT state and remains so for quite some time. Why? The last ACK might get lost, so TCP wants to make sure that no retransmissions of the last ACK are required.
00135 
00136 For high performance servers this can mean that we will run out of socket handles.
00137 
00138 The solution is for the client to terminate the connection ungracefully; instead of sending a FIN packet, the application can send out a RST (reset) packet, this will avoid the whole protocol of closing connections.
00139 
00140 Here the SO_LINGER option is set with timeout of 0 prior to calling close; this results in sending out the RST packet / terminates the connection ungracefully.
00141 
00142 Note that there is still a chance that the RST packet will get lost; in this we can only hope that the server will close it's side of the connection due to some connection idle timeout.
00143  @param ctx - pointer to socket object.
00144 */
00145 
00146 int SOCK_close_with_reset( SOCKCTX *ctx );
00147 
00148 /**
00149  * @}
00150  */
00151 
00152 
00153 #endif
00154