Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound 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 //! contributed by Denis Bider
    00117 class SocketsInitializer
    00118 {
    00119 public:
    00120         SocketsInitializer() {Socket::StartSockets();}
    00121         ~SocketsInitializer() {try {Socket::ShutdownSockets();} catch (...) {}}
    00122 };
    00123
    00124 class SocketReceiver : public NetworkReceiver
    00125 {
    00126 public:
    00127         SocketReceiver(Socket &s);
    00128
    00129 #ifdef USE_BERKELEY_STYLE_SOCKETS
    00130         bool MustWaitToReceive() {return true;}
    00131 #else
    00132         bool MustWaitForResult() {return true;}
    00133 #endif
    00134         void Receive(byte* buf, unsigned int bufLen);
    00135         unsigned int GetReceiveResult();
    00136         bool EofReceived() const {return m_eofReceived;}
    00137
    00138         unsigned int GetMaxWaitObjectCount() const {return 1;}
    00139         void GetWaitObjects(WaitObjectContainer &container);
    00140
    00141 private:
    00142         Socket &m_s;
    00143         bool m_eofReceived;
    00144
    00145 #ifdef USE_WINDOWS_STYLE_SOCKETS
    00146         WindowsHandle m_event;
    00147         OVERLAPPED m_overlapped;
    00148         bool m_resultPending;
    00149         DWORD m_lastResult;
    00150 #else
    00151         unsigned int m_lastResult;
    00152 #endif
    00153 };
    00154
    00155 class SocketSender : public NetworkSender
    00156 {
    00157 public:
    00158         SocketSender(Socket &s);
    00159
    00160 #ifdef USE_BERKELEY_STYLE_SOCKETS
    00161         bool MustWaitToSend() {return true;}
    00162 #else
    00163         bool MustWaitForResult() {return true;}
    00164 #endif
    00165         void Send(const byte* buf, unsigned int bufLen);
    00166         unsigned int GetSendResult();
    00167         void SendEof() {m_s.ShutDown(SD_SEND);}
    00168
    00169         unsigned int GetMaxWaitObjectCount() const {return 1;}
    00170         void GetWaitObjects(WaitObjectContainer &container);
    00171
    00172 private:
    00173         Socket &m_s;
    00174 #ifdef USE_WINDOWS_STYLE_SOCKETS
    00175         WindowsHandle m_event;
    00176         OVERLAPPED m_overlapped;
    00177         bool m_resultPending;
    00178         DWORD m_lastResult;
    00179 #else
    00180         unsigned int m_lastResult;
    00181 #endif
    00182 };
    00183
    00184 //! .
    00185 class SocketSource : public NetworkSource, public Socket
    00186 {
    00187 public:
    00188         SocketSource(socket_t s = INVALID_SOCKET, bool pumpAll = false, BufferedTransformation *attachment = NULL)
    00189                 : NetworkSource(attachment), Socket(s), m_receiver(*this)
    00190         {
    00191                 if (pumpAll)
    00192                         PumpAll();
    00193         }
    00194
    00195 private:
    00196         NetworkReceiver & AccessReceiver() {return m_receiver;}
    00197         SocketReceiver m_receiver;
    00198 };
    00199
    00200 //! .
    00201 class SocketSink : public NetworkSink, public Socket
    00202 {
    00203 public:
    00204         SocketSink(socket_t s = INVALID_SOCKET, unsigned int maxBufferSize=0, bool autoFlush=false)
    00205                 : NetworkSink(maxBufferSize, autoFlush), Socket(s), m_sender(*this) {}
    00206
    00207         void SendEof() {ShutDown(SD_SEND);}
    00208
    00209 private:
    00210         NetworkSender & AccessSender() {return m_sender;}
    00211         SocketSender m_sender;
    00212 };
    00213
    00214 NAMESPACE_END
    00215
    00216 #endif  // #ifdef SOCKETS_AVAILABLE
    00217
    00218 #endif