Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #pragma once
00015
00019 #ifdef WIN32
00020
00021 #include "win32/WS2Include.h"
00022 #define KNET_EWOULDBLOCK WSAEWOULDBLOCK
00023 #define KNET_SOCKET_ERROR SOCKET_ERROR
00024 #define KNET_ACCEPT_FAILURE SOCKET_ERROR
00025
00026 namespace kNet
00027 {
00028 typedef int socklen_t;
00029 }
00030
00031 #else
00032
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035 #include <netinet/in.h>
00036 #include <netdb.h>
00037 #include <errno.h>
00038 #define INVALID_SOCKET (0)
00039 #define KNET_SOCKET_ERROR (-1)
00040 #define KNET_ACCEPT_FAILURE (-1)
00041 #define KNET_EWOULDBLOCK EWOULDBLOCK
00042 #define closesocket close
00043 #define TIMEVAL timeval
00044 #define SD_SEND SHUT_WR
00045 #define SD_BOTH SHUT_RDWR
00046
00047 namespace kNet
00048 {
00049 typedef unsigned int SOCKET;
00050 }
00051 #endif
00052
00053 #include <vector>
00054 #include <list>
00055
00056 #include "SharedPtr.h"
00057 #include "EndPoint.h"
00058 #include "WaitFreeQueue.h"
00059 #include "Event.h"
00060
00061 namespace kNet
00062 {
00063
00065 enum SocketTransportLayer
00066 {
00067 InvalidTransportLayer = 0,
00068 SocketOverUDP,
00069 SocketOverTCP
00070 };
00071
00072 std::string SocketTransportLayerToString(SocketTransportLayer transport);
00073
00074 enum SocketType
00075 {
00076 InvalidSocketType = 0,
00077 ServerListenSocket,
00078 ServerClientSocket,
00079 ClientSocket
00080 };
00081
00082 std::string SocketTypeToString(SocketType type);
00083
00084 typedef int OverlappedTransferTag;
00085
00086 #ifdef WIN32
00087 typedef WSABUF kNetBuffer;
00088 #else
00089 struct kNetBuffer
00090 {
00093 unsigned long len;
00094
00095 char *buf;
00096 };
00097 #endif
00098
00099 struct OverlappedTransferBuffer
00100 {
00101 kNetBuffer buffer;
00102 #ifdef WIN32
00103 WSAOVERLAPPED overlapped;
00104 #endif
00105
00107 int bytesContains;
00108
00109 sockaddr_in from;
00110 socklen_t fromLen;
00111 };
00112
00114 class Socket : public RefCountable
00115 {
00116 public:
00117 Socket();
00118
00119 Socket(SOCKET connection, const EndPoint &localEndPoint, const char *localHostName,
00120 const EndPoint &remoteEndPoint, const char *remoteHostName,
00121 SocketTransportLayer transport, SocketType type, size_t maxSendSize);
00122
00123 Socket(const Socket &);
00124 ~Socket();
00125
00126 Socket &operator=(const Socket &);
00127
00129 void SetSendBufferSize(int bytes);
00131 void SetReceiveBufferSize(int bytes);
00132
00134 int SendBufferSize() const;
00136 int ReceiveBufferSize() const;
00137
00139 bool Connected() const;
00142 bool IsReadOpen() const { return IsOverlappedReceiveReady() || readOpen; }
00144 bool IsWriteOpen() const { return writeOpen; }
00146 void MarkReadClosed() { readOpen = false; }
00148 void MarkWriteClosed() { writeOpen = false; }
00149
00153 bool IsUDPServerSocket() const { return transport == SocketOverUDP && type == ServerListenSocket; }
00155 bool IsUDPSlaveSocket() const { return transport == SocketOverUDP && type == ServerClientSocket; }
00156
00161 void Disconnect();
00163 void Close();
00164
00169 bool Send(const char *data, size_t numBytes);
00170
00176 OverlappedTransferBuffer *BeginSend();
00180 bool EndSend(OverlappedTransferBuffer *send);
00183 void AbortSend(OverlappedTransferBuffer *send);
00184
00185 #ifdef WIN32
00186
00187 int NumOverlappedSendsInProgress() const { return queuedSendBuffers.Size(); }
00189 int MaxOverlappedSendsInProgress() const { return queuedSendBuffers.Capacity(); }
00190 #endif
00191
00192 bool IsOverlappedSendReady();
00194 Event GetOverlappedSendEvent();
00195
00198
00199
00206 size_t Receive(char *dst, size_t maxBytes, EndPoint *endPoint = 0);
00207
00211 OverlappedTransferBuffer *BeginReceive();
00213 void EndReceive(OverlappedTransferBuffer *buffer);
00214 #ifdef WIN32
00215
00216 int NumOverlappedReceivesInProgress() const { return queuedReceiveBuffers.Size(); }
00218 int MaxOverlappedReceivesInProgress() const { return queuedReceiveBuffers.Capacity(); }
00219 #endif
00220
00221 bool IsOverlappedReceiveReady() const;
00223 Event GetOverlappedReceiveEvent();
00224
00226 SocketTransportLayer TransportLayer() const { return transport; }
00227
00229 SocketType Type() const { return type; }
00230
00233 size_t MaxSendSize() const { return maxSendSize; }
00234
00236 const EndPoint &LocalEndPoint() const { return localEndPoint; }
00238 const char *LocalAddress() const { return localHostName.c_str(); }
00240 unsigned short LocalPort() const { return localEndPoint.port; }
00241
00245 const EndPoint &RemoteEndPoint() const { return remoteEndPoint; }
00248 const char *DestinationAddress() const { return remoteHostName.c_str(); }
00251 unsigned short DestinationPort() const { return remoteEndPoint.port; }
00252
00255 std::string ToString() const;
00256
00258 void SetBlocking(bool isBlocking);
00259
00260 SOCKET &GetSocketHandle() { return connectSocket; }
00261
00267 void SetNaglesAlgorithmEnabled(bool enabled);
00268
00269 private:
00271 SOCKET connectSocket;
00272
00274 EndPoint localEndPoint;
00275
00279 std::string localHostName;
00280
00284 EndPoint remoteEndPoint;
00285
00289 sockaddr_in udpPeerAddress;
00290
00294 std::string remoteHostName;
00295
00297 SocketTransportLayer transport;
00298
00305 SocketType type;
00306
00308 size_t maxSendSize;
00309
00311 bool writeOpen;
00312
00314 bool readOpen;
00315
00316 #ifdef WIN32
00317 WaitFreeQueue<OverlappedTransferBuffer*> queuedReceiveBuffers;
00318 WaitFreeQueue<OverlappedTransferBuffer*> queuedSendBuffers;
00319
00321 void FreeOverlappedTransferBuffers();
00322
00323 void EnqueueNewReceiveBuffer(OverlappedTransferBuffer *buffer = 0);
00324 #endif
00325 };
00326
00327 }