Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

socketft.h

00001 #ifndef CRYPTOPP_SOCKETFT_H 00002 #define CRYPTOPP_SOCKETFT_H 00003 00004 #include "config.h" 00005 00006 #ifdef SOCKETS_AVAILABLE 00007 00008 #include "network.h" 00009 #include "queue.h" 00010 00011 #ifdef USE_WINDOWS_STYLE_SOCKETS 00012 # if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) 00013 # error Winsock 1 is not supported by this library. Please include this file or winsock2.h before windows.h. 00014 # endif 00015 #include <winsock2.h> 00016 #include "winpipes.h" 00017 #else 00018 #include <sys/time.h> 00019 #include <sys/types.h> 00020 #include <sys/socket.h> 00021 #include <unistd.h> 00022 #endif 00023 00024 NAMESPACE_BEGIN(CryptoPP) 00025 00026 #ifdef USE_WINDOWS_STYLE_SOCKETS 00027 typedef ::SOCKET socket_t; 00028 #else 00029 typedef int socket_t; 00030 const socket_t INVALID_SOCKET = -1; 00031 // cygwin 1.1.4 doesn't have SHUT_RD 00032 const int SD_RECEIVE = 0; 00033 const int SD_SEND = 1; 00034 const int SD_BOTH = 2; 00035 const int SOCKET_ERROR = -1; 00036 #endif 00037 00038 #ifndef socklen_t 00039 typedef TYPE_OF_SOCKLEN_T socklen_t; // see config.h 00040 #endif 00041 00042 //! wrapper for Windows or Berkeley Sockets 00043 class Socket 00044 { 00045 public: 00046 //! exception thrown by Socket class 00047 class Err : public OS_Error 00048 { 00049 public: 00050 Err(socket_t s, const std::string& operation, int error); 00051 socket_t GetSocket() const {return m_s;} 00052 00053 private: 00054 socket_t m_s; 00055 }; 00056 00057 Socket(socket_t s = INVALID_SOCKET, bool own=false) : m_s(s), m_own(own) {} 00058 Socket(const Socket &s) : m_s(s.m_s), m_own(false) {} 00059 virtual ~Socket(); 00060 00061 bool GetOwnership() const {return m_own;} 00062 void SetOwnership(bool own) {m_own = own;} 00063 00064 operator socket_t() {return m_s;} 00065 socket_t GetSocket() const {return m_s;} 00066 void AttachSocket(socket_t s, bool own=false); 00067 socket_t DetachSocket(); 00068 void CloseSocket(); 00069 00070 void Create(int nType = SOCK_STREAM); 00071 void Bind(unsigned int port, const char *addr=NULL); 00072 void Bind(const sockaddr* psa, socklen_t saLen); 00073 void Listen(int backlog=5); 00074 // the next three functions return false if the socket is in nonblocking mode 00075 // and the operation cannot be completed immediately 00076 bool Connect(const char *addr, unsigned int port); 00077 bool Connect(const sockaddr* psa, socklen_t saLen); 00078 bool Accept(Socket& s, sockaddr *psa=NULL, socklen_t *psaLen=NULL); 00079 void GetSockName(sockaddr *psa, socklen_t *psaLen); 00080 unsigned int Send(const byte* buf, unsigned int bufLen, int flags=0); 00081 unsigned int Receive(byte* buf, unsigned int bufLen, int flags=0); 00082 void ShutDown(int how = SD_SEND); 00083 00084 void IOCtl(long cmd, unsigned long *argp); 00085 bool SendReady(const timeval *timeout); 00086 bool ReceiveReady(const timeval *timeout); 00087 00088 virtual void HandleError(const char *operation) const; 00089 void CheckAndHandleError_int(const char *operation, int result) const 00090 {if (result == SOCKET_ERROR) HandleError(operation);} 00091 void CheckAndHandleError(const char *operation, socket_t result) const 00092 {if (result == SOCKET_ERROR) HandleError(operation);} 00093 #ifdef USE_WINDOWS_STYLE_SOCKETS 00094 void CheckAndHandleError(const char *operation, BOOL result) const 00095 {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);} 00096 #endif 00097 00098 //! look up the port number given its name, returns 0 if not found 00099 static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp"); 00100 //! start Windows Sockets 2 00101 static void StartSockets(); 00102 //! calls WSACleanup for Windows Sockets 00103 static void ShutdownSockets(); 00104 //! returns errno or WSAGetLastError 00105 static int GetLastError(); 00106 //! sets errno or calls WSASetLastError 00107 static void SetLastError(int errorCode); 00108 00109 protected: 00110 virtual void SocketChanged() {} 00111 00112 socket_t m_s; 00113 bool m_own; 00114 }; 00115 00116 class SocketsInitializer 00117 { 00118 public: 00119 SocketsInitializer() {Socket::StartSockets();} 00120 ~SocketsInitializer() {try {Socket::ShutdownSockets();} catch (...) {}} 00121 }; 00122 00123 class SocketReceiver : public NetworkReceiver 00124 { 00125 public: 00126 SocketReceiver(Socket &s); 00127 00128 #ifdef USE_BERKELEY_STYLE_SOCKETS 00129 bool MustWaitToReceive() {return true;} 00130 #else 00131 bool MustWaitForResult() {return true;} 00132 #endif 00133 bool Receive(byte* buf, unsigned int bufLen); 00134 unsigned int GetReceiveResult(); 00135 bool EofReceived() const {return m_eofReceived;} 00136 00137 unsigned int GetMaxWaitObjectCount() const {return 1;} 00138 void GetWaitObjects(WaitObjectContainer &container); 00139 00140 private: 00141 Socket &m_s; 00142 bool m_eofReceived; 00143 00144 #ifdef USE_WINDOWS_STYLE_SOCKETS 00145 WindowsHandle m_event; 00146 OVERLAPPED m_overlapped; 00147 bool m_resultPending; 00148 DWORD m_lastResult; 00149 #else 00150 unsigned int m_lastResult; 00151 #endif 00152 }; 00153 00154 class SocketSender : public NetworkSender 00155 { 00156 public: 00157 SocketSender(Socket &s); 00158 00159 #ifdef USE_BERKELEY_STYLE_SOCKETS 00160 bool MustWaitToSend() {return true;} 00161 #else 00162 bool MustWaitForResult() {return true;} 00163 #endif 00164 void Send(const byte* buf, unsigned int bufLen); 00165 unsigned int GetSendResult(); 00166 void SendEof() {m_s.ShutDown(SD_SEND);} 00167 00168 unsigned int GetMaxWaitObjectCount() const {return 1;} 00169 void GetWaitObjects(WaitObjectContainer &container); 00170 00171 private: 00172 Socket &m_s; 00173 #ifdef USE_WINDOWS_STYLE_SOCKETS 00174 WindowsHandle m_event; 00175 OVERLAPPED m_overlapped; 00176 bool m_resultPending; 00177 DWORD m_lastResult; 00178 #else 00179 unsigned int m_lastResult; 00180 #endif 00181 }; 00182 00183 //! socket-based implementation of NetworkSource 00184 class SocketSource : public NetworkSource, public Socket 00185 { 00186 public: 00187 SocketSource(socket_t s = INVALID_SOCKET, bool pumpAll = false, BufferedTransformation *attachment = NULL) 00188 : NetworkSource(attachment), Socket(s), m_receiver(*this) 00189 { 00190 if (pumpAll) 00191 PumpAll(); 00192 } 00193 00194 private: 00195 NetworkReceiver & AccessReceiver() {return m_receiver;} 00196 SocketReceiver m_receiver; 00197 }; 00198 00199 //! socket-based implementation of NetworkSink 00200 class SocketSink : public NetworkSink, public Socket 00201 { 00202 public: 00203 SocketSink(socket_t s=INVALID_SOCKET, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024) 00204 : NetworkSink(maxBufferSize, autoFlushBound), Socket(s), m_sender(*this) {} 00205 00206 void SendEof() {ShutDown(SD_SEND);} 00207 00208 private: 00209 NetworkSender & AccessSender() {return m_sender;} 00210 SocketSender m_sender; 00211 }; 00212 00213 NAMESPACE_END 00214 00215 #endif // #ifdef SOCKETS_AVAILABLE 00216 00217 #endif

Generated on Wed Jul 21 19:15:34 2004 for Crypto++ by doxygen 1.3.7-20040704