00001 #ifndef RAW_SOCKET_CLASS 00002 #define RAW_SOCKET_CLASS 00003 00004 /*****************************************************************************\ 00005 * * 00006 * Name : raw_socket * 00007 * Author : Chris Koeritz * 00008 * * 00009 * Purpose: * 00010 * * 00011 * Provides access to the operating system's socket methods. * 00012 * * 00013 ******************************************************************************* 00014 * Copyright (c) 1991-$now By Author. This program is free software; you can * 00015 * redistribute it and/or modify it under the terms of the GNU General Public * 00016 * License as published by the Free Software Foundation; either version 2 of * 00017 * the License or (at your option) any later version. This is online at: * 00018 * http://www.fsf.org/copyleft/gpl.html * 00019 * Please send any updates to: fred@gruntose.com * 00020 \*****************************************************************************/ 00021 00022 // NOTE: This class does not provide any sort of synchronization of the 00023 // sockets involved. If you have multiple threads arbitrarily calling select 00024 // and read, then some selects will claim the socket was disconnected (since 00025 // the other thread might have grabbed the data that seemed to be ready but 00026 // then wasn't--a sign of a disconnect). Ensure that your accesses of the 00027 // socket are serialized. 00028 00029 #include "sockets_dll.h" 00030 00031 #include <basis/object_base.h> 00032 00033 // forward. 00034 class fd_set_wrapper; 00035 class tcpip_stack; 00036 00037 class SOCKETS_CLASS_STYLE raw_socket : public virtual object_base 00038 { 00039 public: 00040 raw_socket(); 00041 00042 ~raw_socket(); 00043 00044 IMPLEMENT_CLASS_NAME("raw_socket"); 00045 00046 // int open( 00047 //hmmm... 00048 00049 int close(u_int &socket); 00050 // disconnects, destroys and resets the "socket" to zero. 00051 00052 int ioctl(u_int socket, int request, void *argp) const; 00053 // manipulates the device parameters for the "socket". 00054 00055 bool set_non_blocking(u_int socket, bool non_blocking = true); 00056 // makes the "socket" into a non-blocking socket if "non_blocking" is true. 00057 // if "non_blocking" is false, then the socket is reset to blocking mode. 00058 00059 bool set_nagle_algorithm(u_int socket, bool use_nagle = true); 00060 // sets the nagle algorithm on "socket" if "use_nagle" is true. note that 00061 // true is the default when a socket is created; to change that for the 00062 // socket, "use_nagle" should be false. 00063 00064 bool set_broadcast(u_int socket, bool broadcasting = true); 00065 // sets broadcast mode on the socket so that it can receive packets that 00066 // are broadcast to the network. 00067 00068 bool set_reuse_address(u_int socket, bool reuse = true); 00069 // sets the socket to allow an address to be re-used when it's already 00070 // in use, rather than getting a bind error. 00071 00072 bool set_keep_alive(u_int socket, bool keep_alive = true); 00073 // marks a connected-mode socket so that keep alive packets will be sent 00074 // occasionally to ensure that a disconnection is noticed. 00075 00076 static istring interest_name(int to_name); 00077 // returns the textual form for the interests set in "to_name". 00078 00079 // outlines any special constraints on the select invocation. 00080 enum select_types { 00081 SELECTING_JUST_WRITE = 0x1, 00082 SELECTING_JUST_READ = 0x2 00083 }; 00084 00085 int select(u_int socket, int selection_mode, int timeout = 0) const; 00086 // this is similar to the low-level select on a bsd socket. usually this 00087 // will return events of any type--read, write and exception. exceptions 00088 // will always be cause for a return, but if you just want to look at a 00089 // read condition, include the JUST_READ flag in the "selection_mode". to 00090 // just check for write, add the JUST_WRITE flag. this function returns a 00091 // bitwise ORed value from the different types of 'socket_interests' (see 00092 // tcpip definitions, which is where the enum is currently stored). if 00093 // there are no special conditions noted on the socket, then zero is 00094 // returned. if the "timeout" is zero, the function will return right 00095 // away. if "timeout" (measured in milliseconds) is non-zero, then the 00096 // function will wait until the condition becomes true or the "timeout" 00097 // elapses. note: no infinite timeouts are provided here. 00098 00099 int select(int_array &read_sox, int_array &write_sox, int timeout = 0) const; 00100 // similar to select above, but operates on a list of sockets in the 00101 // "read_sox" and "write_sox". the "read_sox" are checked to see whether 00102 // those sockets have data pending that could be read. the "write_sox" are 00103 // checked to see if the sockets are currently writable without blocking. 00104 // if any sockets have events applicable to the "selection_mode", then they 00105 // will still be present in the lists when the call returns. zero is 00106 // returned if absolutely nothing happened during the "timeout" period; 00107 // otherwise, a non-zero number is returned but the individual sockets 00108 // must still be inspected to determine what happened. 00109 00110 int analyze_select_result(u_int socket, int mode, fd_set_wrapper &read_list, 00111 fd_set_wrapper &write_list, fd_set_wrapper &exceptions) const; 00112 // examines the "socket" in the fd_sets passed in and returns a result 00113 // based on those sets and the "mode". 00114 00115 private: 00116 tcpip_stack *_stack; 00117 00118 int test_readability(u_int socket) const; 00119 // checks on the readability state for the "socket", assuming that select() 00120 // reported the socket as readable, and returns either SI_ERRONEOUS, 00121 // SI_READABLE or SI_DISCONNECTED based on what ioctl() says about it. 00122 00123 int inner_select(u_int socket, int selection_mode, int timeout, 00124 fd_set_wrapper &read_list, fd_set_wrapper &write_list, 00125 fd_set_wrapper &exceptions) const; 00126 // intermediate function that doesn't attempt to fully analyze the select 00127 // result. the returned value will be non-zero if something interesting 00128 // is happening on the socket. if that value is SI_ERRONEOUS, then 00129 // something bad happened to the socket. the other non-zero value is 00130 // SI_BASELINE, which means the socket has something to report in the 00131 // fd_set parameters. 00132 }; 00133 00134 #endif 00135
1.5.1