00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef __SOCKET_H__
00044 #define __SOCKET_H__
00045
00046 #include <sys/stat.h>
00047 #include <stdlib.h>
00048 #include <stdio.h>
00049 #include <stdarg.h>
00050 #include <errno.h>
00051
00052 #if defined(_LINUX) || defined (_DARWIN)
00053 #include <sys/socket.h>
00054 #include <netinet/in.h>
00055 #include <arpa/inet.h>
00056 #include <netinet/tcp.h>
00057 #include <netinet/ip.h>
00058 #include <netdb.h>
00059 #endif
00060 #ifdef _LINUX
00061 #include <linux/if_packet.h>
00062 #include <linux/if_packet.h>
00063 #include <linux/if_ether.h>
00064 #include <linux/if.h>
00065 #include <sys/sendfile.h>
00066 #endif
00067 #if defined(_LINUX) || defined (_DARWIN)
00068 #include <sys/time.h>
00069 #include <sys/uio.h>
00070 #include <unistd.h>
00071 #include <fcntl.h>
00072 #endif
00073 #ifdef WIN32
00074 #include <io.h>
00075 #include <winsock2.h>
00076 #include <Ws2tcpip.h>
00077
00078 #define IPTOS_LOWDELAY 0x10
00079
00080 #endif
00081 #include "Host.h"
00082 #include "StatTimer.h"
00083
00084
00085
00086
00087 #ifndef INVALID_SOCKET
00088 #define INVALID_SOCKET ~(0)
00089 #endif
00090
00091 #define SOCKET_SENDFILE_BLOCKSIZE 8192
00092
00099 class CSimpleSocket {
00100 public:
00102 typedef enum
00103 {
00104 Receives = SHUT_RD,
00105 Sends = SHUT_WR,
00106 Both = SHUT_RDWR
00107 } CShutdownMode;
00108
00110 typedef enum
00111 {
00112 SocketTypeInvalid,
00113 SocketTypeTcp,
00114 SocketTypeUdp,
00115 SocketTypeTcp6,
00116 SocketTypeUdp6,
00117 SocketTypeRaw
00118 } CSocketType;
00119
00121 typedef enum
00122 {
00123 SocketError = -1,
00124 SocketSuccess = 0,
00125 SocketInvalidSocket,
00126 SocketInvalidAddress,
00127 SocketInvalidPort,
00128 SocketConnectionRefused,
00129 SocketTimedout,
00130 SocketEwouldblock,
00131 SocketNotconnected,
00132 SocketEinprogress,
00133 SocketInterrupted,
00134 SocketConnectionAborted,
00135 SocketProtocolError,
00136 SocketFirewallError,
00137 SocketInvalidSocketBuffer,
00138 SocketConnectionReset,
00139 SocketAddressInUse,
00140 SocketInvalidPointer,
00141 SocketEunknown
00142 } CSocketError;
00143
00144 public:
00145 CSimpleSocket(CSocketType type = SocketTypeTcp);
00146 CSimpleSocket(CSimpleSocket &socket);
00147
00148 virtual ~CSimpleSocket()
00149 {
00150 if (m_pBuffer != NULL)
00151 {
00152 delete [] m_pBuffer;
00153 m_pBuffer = NULL;
00154 }
00155 };
00156
00161 virtual bool Initialize(void);
00162
00165 virtual bool Close(void);
00166
00173 virtual bool Shutdown(CShutdownMode nShutdown);
00174
00181 virtual bool Select(void) { return Select(0,0); };
00182
00190 virtual bool Select(int32 nTimeoutSec, int32 nTimeoutUSec);
00191
00195 virtual bool IsSocketValid(void) { return (m_socket != SocketError); };
00196
00200 void TranslateSocketError(void);
00201
00207 virtual int32 Receive(int32 nMaxBytes = 1);
00208
00215 virtual int32 Send(const uint8 *pBuf, size_t bytesToSend);
00216
00225 virtual int32 Send(const struct iovec *sendVector, int32 nNumItems);
00226
00239 virtual int32 SendFile(int32 nOutFd, int32 nInFd, off_t *pOffset, int32 nCount);
00240
00243 bool IsNonblocking(void) { return (m_bIsBlocking == false); };
00244
00247 bool SetBlocking(void);
00248
00251 bool SetNonblocking(void);
00252
00257 uint8 *GetData(void) { return m_pBuffer; };
00258
00262 int32 GetBytesReceived(void) { return m_nBytesReceived; };
00263
00267 int32 GetBytesSent(void) { return m_nBytesSent; };
00268
00284 bool SetOptionLinger(bool bEnable, uint16 nTime);
00285
00290 bool SetOptionReuseAddr();
00291
00295 int32 GetConnectTimeoutSec(void) { return m_stConnectTimeout.tv_sec; };
00296
00300 int32 GetConnectTimeoutUSec(void) { return m_stConnectTimeout.tv_usec; };
00301
00312 void SetConnectTimeout(int32 nConnectTimeoutSec, int32 nConnectTimeoutUsec = 0)
00313 {
00314 m_stConnectTimeout.tv_sec = nConnectTimeoutSec;
00315 m_stConnectTimeout.tv_usec = nConnectTimeoutUsec;
00316 };
00317
00321 int32 GetReceiveTimeoutSec(void) { return m_stRecvTimeout.tv_sec; };
00322
00326 int32 GetReceiveTimeoutUSec(void) { return m_stRecvTimeout.tv_usec; };
00327
00338 bool SetReceiveTimeout(int32 nRecvTimeoutSec, int32 nRecvTimeoutUsec = 0);
00339
00345 bool SetMulticast(bool bEnable, uint8 multicastTTL = 1);
00346
00349 bool GetMulticast() { return m_bIsMulticast; };
00350
00353 bool BindInterface(uint8 *pInterface);
00354
00358 int32 GetSendTimeoutSec(void) { return m_stSendTimeout.tv_sec; };
00359
00363 int32 GetSendTimeoutUSec(void) { return m_stSendTimeout.tv_usec; };
00364
00368 bool SetSendTimeout(int32 nSendTimeoutSec, int32 nSendTimeoutUsec = 0);
00369
00374 CSocketError GetSocketError(void) { return m_socketErrno; };
00375
00378 uint32 GetTotalTimeMs() { return m_timer.GetMilliSeconds(); };
00379
00382 uint32 GetTotalTimeUsec() { return m_timer.GetMicroSeconds(); };
00383
00387 int GetSocketDscp(void);
00388
00393 bool SetSocketDscp(int nDscp);
00394
00397 SOCKET GetSocketDescriptor() { return m_socket; };
00398
00401 CSocketType GetSocketType() { return m_nSocketType; };
00402
00405 uint8 *GetClientAddr() { return (uint8 *)inet_ntoa(m_stClientSockaddr.sin_addr); };
00406
00409 int16 GetClientPort() { return m_stClientSockaddr.sin_port; };
00410
00413 uint8 *GetServerAddr() { return (uint8 *)inet_ntoa(m_stServerSockaddr.sin_addr); };
00414
00417 int16 GetServerPort() { return ntohs(m_stServerSockaddr.sin_port); };
00418
00422 uint16 GetReceiveWindowSize() { return GetWindowSize(SO_RCVBUF); };
00423
00427 uint16 GetSendWindowSize() { return GetWindowSize(SO_SNDBUF); };
00428
00432 uint16 SetReceiveWindowSize(uint16 nWindowSize) { return SetWindowSize(SO_RCVBUF, nWindowSize); };
00433
00437 uint16 SetSendWindowSize(uint16 nWindowSize) { return SetWindowSize(SO_SNDBUF, nWindowSize); };
00438
00441 bool DisableNagleAlgoritm();
00442
00445 bool EnableNagleAlgoritm();
00446
00447
00448 protected:
00451 void SetSocketError(CSimpleSocket::CSocketError error) { m_socketErrno = error; };
00452
00455 void SetSocketHandle(SOCKET socket) { m_socket = socket; };
00456
00457 private:
00460 uint16 GetWindowSize(uint32 nOptionName);
00461
00464 uint16 SetWindowSize(uint32 nOptionName, uint32 nWindowSize);
00465
00466
00476 int32 Writev(const struct iovec *pVector, size_t nCount);
00477
00480 bool Flush();
00481
00482 CSimpleSocket *operator=(CSimpleSocket &socket);
00483
00484 protected:
00485 SOCKET m_socket;
00486 CSocketError m_socketErrno;
00487 uint8 *m_pBuffer;
00488 int32 m_nBufferSize;
00489 int32 m_nSocketDomain;
00490 CSocketType m_nSocketType;
00491 int32 m_nBytesReceived;
00492 int32 m_nBytesSent;
00493 uint32 m_nFlags;
00494 bool m_bIsBlocking;
00495 bool m_bIsMulticast;
00496 struct timeval m_stConnectTimeout;
00497 struct timeval m_stRecvTimeout;
00498 struct timeval m_stSendTimeout;
00499 struct sockaddr_in m_stServerSockaddr;
00500 struct sockaddr_in m_stClientSockaddr;
00501 struct sockaddr_in m_stMulticastGroup;
00502 struct linger m_stLinger;
00503 CStatTimer m_timer;
00504 #ifdef WIN32
00505 WSADATA m_hWSAData;
00506 #endif
00507 fd_set m_writeFds;
00508 fd_set m_readFds;
00509 fd_set m_errorFds;
00510 };
00511
00512
00513 #endif
00514