Simple tools for networking / objects in plain C Snapshot
|
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