Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
Socket.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef Socket_h_DEFINED 00003 #define Socket_h_DEFINED 00004 00005 #ifdef PLATFORM_APERIOS 00006 # include <ant.h> 00007 # include <Types.h> 00008 #else 00009 # include <sys/socket.h> 00010 #endif 00011 #include <stdarg.h> 00012 #include <stdlib.h> 00013 #include <string> 00014 00015 //! holds socket enumerations and constants 00016 namespace SocketNS { 00017 00018 #ifdef PLATFORM_APERIOS 00019 const int _SYS_SOCK_STREAM=1; //!< aperios doesn't provide SOCK_STREAM, so we will initialize them to these values 00020 const int _SYS_SOCK_DGRAM=2; //!< aperios doesn't provide SOCK_DGRAM, so we will initialize them to these values 00021 #else 00022 //this is why you shouldn't use #define to declare constant values... grrr 00023 const int _SYS_SOCK_STREAM=SOCK_STREAM; 00024 const int _SYS_SOCK_DGRAM=SOCK_DGRAM; 00025 # ifdef SOCK_STREAM 00026 # undef SOCK_STREAM 00027 # endif 00028 # ifdef SOCK_DGRAM 00029 # undef SOCK_DGRAM 00030 # endif 00031 #endif 00032 //! Specifies transport type. TCP is usually a good idea 00033 enum TransportType_t { 00034 SOCK_STREAM=_SYS_SOCK_STREAM, //!< TCP: guaranteed delivery, higher overhead 00035 SOCK_DGRAM=_SYS_SOCK_DGRAM //!< UDP: no guarantees, low overhead 00036 }; 00037 00038 //! Internal TCP/UDP Connection State 00039 enum ConnectionState { 00040 CONNECTION_CLOSED, 00041 CONNECTION_CONNECTING, 00042 CONNECTION_CONNECTED, 00043 CONNECTION_LISTENING, 00044 CONNECTION_CLOSING, 00045 CONNECTION_ERROR 00046 }; 00047 00048 //! Chooses between blocking and non-blocking Wireless Input, Output. Blocking wireless output from the main process will affect the performance of the Aibo, and should only be used for debugging purposes 00049 enum FlushType_t { 00050 FLUSH_NONBLOCKING=0, //!< Writes and Reads return immediately, and are processed by another process, so Main can continue to run. Non-blocking reads require specifying a callback function to handle data received 00051 FLUSH_BLOCKING //!< Blocking writes are a good idea for debugging - a blocking write will be transmitted before execution continues to the next statement. Blocking reads should be avoided, since they'll cause a significant slow down in the main process 00052 }; 00053 00054 }; 00055 00056 using namespace SocketNS; 00057 00058 #ifndef PLATFORM_APERIOS 00059 typedef unsigned char byte; 00060 #endif 00061 00062 //! Tekkotsu wireless Socket class 00063 /*! 00064 * For more information on using wireless, please read the following tutorials: 00065 * - <a href="../AiboMon.html">TekkotsuMon</a> 00066 * - <a href="../Wireless.html">TCP/IP</a> 00067 * - <a href="../RemoteProcess.html">Remote Processing OPENR</a> 00068 * Tekkotsu Wireless and Remote Processing OPENR provide different 00069 * interfaces to comparable wireless functionality. 00070 * 00071 * The networking interface needs more documentation. It also needs a 00072 * cleanup. In the mean time, take a look at the TekkotsuMon objects 00073 * in <i>Tekkotsu</i><tt>/Behaviors/Mon</tt>. They all listen for new 00074 * connections. Unfortunately, at the momement there are no examples 00075 * of outgoing connections, but it should give you a pretty good idea 00076 * how to start moving. 00077 */ 00078 00079 class Socket { 00080 friend class Wireless; 00081 00082 public: 00083 int sock; //!< unique non-negative integer representing socket. Serves as index into socket Objects array 00084 00085 public: 00086 //! constructor 00087 explicit Socket(int sockn) 00088 : sock(sockn), trType(), flType(FLUSH_NONBLOCKING), verbosity(0), 00089 endpoint(), state(CONNECTION_CLOSED), sendBufSize(), recvBufSize(), 00090 sendSize(0), sentSize(0), recvSize(0), writeSize(0), readSize(0), 00091 tx(false), rx(false), sendBuffer(), sendData(NULL), writeData(NULL), 00092 recvBuffer(), recvData(NULL), readData(NULL), server_port(0), 00093 rcvcbckfn(NULL), peer_addr(-1), peer_port(-1), textForward(false), textForwardBuf(NULL), 00094 forwardSock(NULL), daemon(false) 00095 { 00096 #ifndef PLATFORM_APERIOS 00097 endpoint=-1; 00098 #endif 00099 } 00100 virtual ~Socket(); //!< destructor 00101 00102 //! use getWriteBuffer to get a memory address to write bytes to, for 00103 //! subsequent writing to a connection. 00104 /*! 00105 * The getWriteBuffer-write(int) combo eliminates one buffer copy. You 00106 * don't need to use getWriteBuffer with write(byte*, int) 00107 * @return pointer to the current position in the current write buffer for this socket or NULL on error 00108 * @param bytesreq maximum number of bytes the caller intends to set before the write method is called */ 00109 byte* getWriteBuffer(int bytesreq); 00110 00111 //! writes the specified number of bytes starting at the pointer returned. 00112 /*! 00113 * in a (prior) call to getWriteBufer 00114 * @param size number of bytes to be sent from the current write buffer 00115 */ 00116 void write(int size); 00117 00118 //! Blocking read. NOT IMPLEMENTED 00119 /*! 00120 * Tries to read upto receive buffer size worth of data from this socket. 00121 * 00122 * Blocking read is currently broken - it will be fixed in the next release 00123 * @return number of bytes read or -1 on error 00124 */ 00125 int read(); 00126 00127 //! getReadBuffer is used with blocking read's NOT IMPLEMENTED 00128 /*! 00129 * The read(void) and getReadBuffer combo eliminates one buffer copy. You 00130 * don't need to use getReadBuffer with read(byte*, int) 00131 * 00132 * Blocking read is currently broken - it will be fixed in the next release 00133 * @return pointer to the buffer the previous call to blocking read wrote into or NULL if no data was read 00134 */ 00135 byte* getReadBuffer(); 00136 00137 //! initialize socket member variables. This is different from the constructor since sockets are reused 00138 void init(); 00139 00140 //! Chooses between blocking and non-blocking input, output. 00141 /*! This function 00142 * can only be called when a socket is disconnected, since it is a bad 00143 * idea to mix blocking and non-blocking input, output. 00144 * The default for a socket is non-blocking 00145 * @return 0 on success 00146 */ 00147 int setFlushType(FlushType_t fType); 00148 00149 //! can choose between different transports; will reset the socket 00150 int setTransport(TransportType_t tr); 00151 00152 //!causes this socket to forward output to stdout if it is not connected, call setForward(NULL) to unset 00153 void setTextForward() { textForward=true; forwardSock=NULL; } 00154 00155 //!causes this socket to forward output to @a sock if it is not connected, pass NULL to unset 00156 void setForward(Socket * forsock) { forwardSock=forsock; textForward=false; } 00157 00158 //! Picks a level of verbosity for filtering pprintf commands. 00159 /*! The higher the 00160 * verbosity, the more the number of messages printed. This is useful 00161 * for filtering out non-important messages with very little processor 00162 * cost. Default is 0. 00163 * @param verbose the higher the value of verbose, the more the output 00164 */ 00165 void setVerbosity(int verbose) { verbosity=verbose; } 00166 00167 //! Standard write - writes specified amount of data from a buffer to a 00168 //! connection 00169 /*! You might want to consider the getWriteBuffer-write(int) combo if you 00170 * call this often 00171 * @param buf buffer to write from 00172 * @param size number of bytes to write 00173 * @return the number of bytes actually written or -1 on error 00174 */ 00175 int write(const byte *buf, int size); 00176 00177 //! Blocking read (NOT IMPLEMENTED) 00178 /*! You might want to consider the read(void) and getReadBuffer combo if you 00179 * call this often 00180 * 00181 * Blocking read is currently broken - it will be fixed in the next release 00182 * @param buf buffer to write from 00183 * @param size number of bytes to write 00184 * @return number of bytes actually read 00185 */ 00186 int read(byte *buf, int size); 00187 00188 //! It's standard stuff. man 3 printf on most systems should give you more 00189 //! information 00190 int printf(const char *fmt, ...) __attribute__((format(printf,2,3))); 00191 00192 //! It's standard stuff. man 3 printf on most systems should give you more 00193 //! information 00194 int vprintf(const char *fmt, va_list al) __attribute__ ((format (printf, 2, 0))); 00195 00196 //! Similar to printf, except it takes an extra first argument. 00197 /*! If vlevel is than or equal to the current #verbosity level, 00198 * the string will be printed else it will be ignored. 00199 * @param vlevel if (vlevel<=verbosity) print, else ignore 00200 * @param fmt same as the standard printf's format string 00201 */ 00202 int pprintf(int vlevel, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); 00203 00204 //! Initiate blocking or nonblocking write transfer depending on the type 00205 //! of socket. 00206 /*! All write commands on the socket will implicity call this. You 00207 * don't need to call it, unless you're implementing your own write 00208 */ 00209 void flush(); 00210 00211 //! returns #daemon 00212 bool getDaemon() const { return daemon; } 00213 00214 int getPeerAddress() const { return peer_addr; } //!< returns the address of the remote host in local host byte order 00215 std::string getPeerAddressAsString() const; //!< returns the address of the remote host as a human-readable string 00216 int getPeerPort() const { return peer_port; } //!< returns the port number that the remote host's socket is on 00217 00218 protected: 00219 TransportType_t trType; //!< stores choice between transports (UDP or TCP (aka Datagram or Stream)) 00220 FlushType_t flType; //!< blocking or non-blocking flushes... note that blocking flushes only block on the handoff to the system, not actual transmission (at least under aperios) 00221 00222 int verbosity; //!< can be used to filter calls to pprintf 00223 00224 #ifdef PLATFORM_APERIOS 00225 typedef antSharedBuffer buf_t; //!< the Aibo Networking Toolkit buffer data structure 00226 typedef antModuleRef endp_t; //!< the Aibo Networking Toolkit endpoint data structure 00227 #else 00228 typedef char* buf_t; //!< a general buffer 00229 typedef int endp_t; //!< a unix socket descriptor 00230 #endif 00231 00232 endp_t endpoint; //!< holds the endpoint data structure for the host OS 00233 ConnectionState state; //!< an enum representing the current state of the socket 00234 00235 int sendBufSize; //!< the size of the buffer for #sendData and #writeData 00236 int recvBufSize; //!< the size of the buffer for #readData and #recvData 00237 int sendSize; //!< the size of #sendData (total amount of data from last flush) 00238 int sentSize; //!< the sent portion of #sendData (amount of data which has been sent to system so far) 00239 int recvSize; //!< the size of #recvData (total amount of data returned by system) 00240 int writeSize; //!< the size of #writeData (amount of data so far ready to be flushed) 00241 int readSize; //!< the size of #readData (not used) 00242 bool tx; //!< a flag set when #sendData is in the process of being sent to the system 00243 bool rx; //!< not used, see #readData 00244 00245 buf_t sendBuffer; //!< under aperios, a pointer to a shared region with the ip stack; under other OS, a pointer to a normal char * buffer 00246 byte *sendData; //!< a region within #sendBuffer, holding data in the process of being sent 00247 byte *writeData; //!< a region within #sendBuffer, holds data still being filled in by user code, not yet flushed 00248 00249 buf_t recvBuffer; //!< under aperios, a pointer to a shared region with the ip stack; under other OS, a pointer to a normal char * buffer 00250 byte *recvData; //!< a region within #recvBuffer, holding data either just filled in by ip stack (during call to #rcvcbckfn), or in the process of being filled in (any other time) 00251 byte *readData; //!< not used (available for double buffering, but not implemented) 00252 00253 int server_port; //!< if the socket is a server socket, this is the port it is listening on 00254 int (*rcvcbckfn) (char*, int); //!< pointer to callback function, called after #recvData has been filled in 00255 00256 int peer_addr; //!< inet address of peer (if connected) or last message sender (if udp and bound); -1 otherwise (in host byte-order, not network byte-order!) 00257 int peer_port; //!< port of peer (if connected) or last message sender (if udp and bound); -1 otherwise 00258 00259 bool textForward; //!< if true, when data is sent to the socket and the socket is not current connected, the data will be sent to stdout (overridden by #forwardSock) 00260 char* textForwardBuf; //!< temporary buffer allocated in getWriteBuffer() and freed in write(), if the output is destined for stdout (#textForward) 00261 Socket * forwardSock; //!< if non-NULL, output will be sent to this socket if the current socket is not otherwise connected (overrides #textForward) 00262 00263 bool daemon; //!< if true, the socket will automatically be reopened after any closure (manual or otherwise) 00264 00265 protected: 00266 Socket(const Socket&); //!< copy constructor, don't call 00267 Socket& operator= (const Socket&); //!< assignment operator, don't call 00268 }; 00269 00270 extern Socket* sout; //!< the standard tekkotsu in/out console (default port 10001) 00271 extern Socket* serr; //!< the standard tekkotsu error output (default port 10002) 00272 00273 /*! @file 00274 * @brief Defines Tekkotsu wireless Socket class, also sout and serr 00275 * @author alokl (Creator) 00276 * 00277 * $Author: ejt $ 00278 * $Name: tekkotsu-2_4_1 $ 00279 * $Revision: 1.23 $ 00280 * $State: Exp $ 00281 * $Date: 2005/08/07 04:11:04 $ 00282 */ 00283 00284 #endif |
Tekkotsu v2.4.1 |
Generated Tue Aug 16 16:32:48 2005 by Doxygen 1.4.4 |