Panda3D
|
00001 #ifndef __SOCKET_TCP_H__ 00002 #define __SOCKET_TCP_H__ 00003 00004 #include "pandabase.h" 00005 #include "socket_ip.h" 00006 00007 ///////////////////////////////////////////////////////////////////// 00008 // Class : Socket_TCP 00009 // 00010 // Description : Base functionality for a TCP connected socket 00011 // This class is pretty useless by itself but it does hide some of the 00012 // platform differences from machine to machine 00013 // 00014 ///////////////////////////////////////////////////////////////////// 00015 class EXPCL_PANDA_NATIVENET Socket_TCP : public Socket_IP 00016 { 00017 public: 00018 PUBLISHED: 00019 inline Socket_TCP(SOCKET); 00020 inline Socket_TCP() { }; 00021 inline int SetNoDelay(bool flag = true); 00022 inline int SetLinger(int interval_seconds = 0); 00023 inline int DontLinger(); 00024 inline int SetSendBufferSize(int insize); 00025 //inline bool ActiveOpen(const Socket_Address & theaddress); 00026 inline bool ActiveOpen(const Socket_Address & theaddress, bool setdelay); 00027 inline bool ActiveOpenNonBlocking(const Socket_Address & theaddress); 00028 inline bool ErrorIs_WouldBlocking(int err); 00029 inline bool ShutdownSend(); 00030 inline int SendData(const std::string &str); 00031 // inline int RecvData( std::string &str, int max_len); 00032 00033 std::string RecvData(int max_len); 00034 public: 00035 inline int SendData(const char * data, int size); 00036 inline int RecvData(char * data, int size); 00037 00038 public: 00039 static TypeHandle get_class_type() { 00040 return _type_handle; 00041 } 00042 static void init_type() { 00043 Socket_IP::init_type(); 00044 register_type(_type_handle, "Socket_TCP", 00045 Socket_IP::get_class_type()); 00046 } 00047 virtual TypeHandle get_type() const { 00048 return get_class_type(); 00049 } 00050 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00051 00052 private: 00053 static TypeHandle _type_handle; 00054 }; 00055 00056 ////////////////////////////////////////////////////////////// 00057 // Function name : Socket_TCP::Socket_TCP 00058 // Description : 00059 ////////////////////////////////////////////////////////////// 00060 inline Socket_TCP::Socket_TCP(SOCKET sck) : ::Socket_IP(sck) 00061 { 00062 } 00063 00064 //////////////////////////////////////////////////////////////////// 00065 // Function name : SetNoDelay 00066 // Description : Disable Nagle algorithm. Don't delay send to coalesce packets 00067 //////////////////////////////////////////////////////////////////// 00068 inline int Socket_TCP::SetNoDelay(bool flag) 00069 { 00070 int nodel = flag; 00071 int ret1; 00072 ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel)); 00073 00074 if (ret1 != 0) 00075 return BASIC_ERROR; 00076 00077 return ALL_OK; 00078 } 00079 00080 //////////////////////////////////////////////////////////////////// 00081 // Function name : SetLinger 00082 // Description : will control the behavior of SO_LINGER for a TCP socket 00083 //////////////////////////////////////////////////////////////////// 00084 int Socket_TCP::SetLinger(int interval_seconds) 00085 { 00086 linger ll; 00087 ll.l_linger = interval_seconds; 00088 ll.l_onoff = 1; 00089 int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger)); 00090 if (ret1 != 0) 00091 return BASIC_ERROR; 00092 return ALL_OK; 00093 } 00094 00095 //////////////////////////////////////////////////////////////////// 00096 // Function name : Socket_TCP::DontLinger 00097 // Description : Turn off the linger flag. The socket will quickly release 00098 // buffered items and free up OS resources. You may lose 00099 // a stream if you use this flag and do not negotiate the close 00100 // at the application layer. 00101 //////////////////////////////////////////////////////////////////// 00102 int Socket_TCP::DontLinger() 00103 { 00104 linger ll; 00105 ll.l_linger = 0; 00106 ll.l_onoff = 0; 00107 int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger)); 00108 if (ret1 != 0) 00109 return BASIC_ERROR; 00110 return ALL_OK; 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function name : SetSendBufferSize 00115 // Description : Just like it sounds. Sets a buffered socket recv buffer size. 00116 // This function does not refuse ranges outside hard-coded OS 00117 // limits 00118 //////////////////////////////////////////////////////////////////// 00119 int Socket_TCP::SetSendBufferSize(int insize) 00120 { 00121 if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_SNDBUF, (char *) &insize, sizeof(int))) 00122 return BASIC_ERROR; 00123 return ALL_OK; 00124 } 00125 00126 //////////////////////////////////////////////////////////////////// 00127 // Function name : ActiveOpen 00128 // Description : This function will try and set the socket up for active open to a specified 00129 // address and port provided by the input parameter 00130 //////////////////////////////////////////////////////////////////// 00131 bool Socket_TCP::ActiveOpen(const Socket_Address & theaddress, bool setdelay) 00132 { 00133 _socket = DO_NEWTCP(); 00134 if (_socket == BAD_SOCKET) 00135 return false; 00136 00137 if(setdelay) 00138 SetNoDelay(); 00139 00140 if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0) 00141 return ErrorClose(); 00142 00143 return true; 00144 } 00145 00146 00147 //////////////////////////////////////////////////////////////////// 00148 // Function name : ActiveOpenNonBlocking 00149 // Description : This function will try and set the socket up for active open to a specified 00150 // address and port provided by the input parameter (non-blocking version) 00151 //////////////////////////////////////////////////////////////////// 00152 bool Socket_TCP::ActiveOpenNonBlocking(const Socket_Address & theaddress) 00153 { 00154 _socket = DO_NEWTCP(); 00155 if (_socket == BAD_SOCKET) 00156 return false; 00157 00158 SetNonBlocking(); 00159 SetReuseAddress(); 00160 00161 if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0) { 00162 if (GETERROR() != LOCAL_CONNECT_BLOCKING) 00163 { 00164 printf(" None Blockign Connect Error %d",GETERROR()); 00165 return ErrorClose(); 00166 } 00167 } 00168 00169 return true; 00170 } 00171 00172 //////////////////////////////////////////////////////////////////// 00173 // Function name : Socket_TCP::SendData 00174 // Description : Ok Lets Send the Data 00175 // 00176 // Return type : int 00177 // - if error 00178 // 0 if socket closed for write or lengh is 0 00179 // + bytes writen ( May be smaller than requested) 00180 //////////////////////////////////////////////////////////////////// 00181 inline int Socket_TCP::SendData(const char * data, int size) 00182 { 00183 return DO_SOCKET_WRITE(_socket, data, size); 00184 } 00185 00186 //////////////////////////////////////////////////////////////////// 00187 // Function name : Socket_TCP::RecvData 00188 // Description : Read the data from the connection 00189 // 00190 // Return type : int 00191 // - if error 00192 // 0 if socket closed for read or length is 0 00193 // + bytes read ( May be smaller than requested) 00194 //////////////////////////////////////////////////////////////////// 00195 inline int Socket_TCP::RecvData(char * data, int len) 00196 { 00197 int ecode = DO_SOCKET_READ(_socket, data, len); 00198 return ecode; 00199 } 00200 00201 //////////////////////////////////////////////////////////////////// 00202 // Function name : Socket_TCP::RecvData 00203 // Description : Read the data from the connection 00204 // 00205 // Return type : int 00206 // - if error 00207 // 0 if socket closed for read or length is 0 00208 // + bytes read ( May be smaller than requested) 00209 //////////////////////////////////////////////////////////////////// 00210 inline std::string Socket_TCP::RecvData(int max_len) 00211 { 00212 std::string str; 00213 char *buffer = (char *) malloc(max_len+1); 00214 int ecode = RecvData(buffer,max_len); 00215 if(ecode > 0) 00216 str.assign(buffer,ecode); 00217 00218 free(buffer); 00219 return str; 00220 }; 00221 00222 00223 inline bool Socket_TCP::ErrorIs_WouldBlocking(int err) 00224 { 00225 return (GETERROR() == LOCAL_BLOCKING_ERROR); 00226 } 00227 00228 inline bool Socket_TCP::ShutdownSend() 00229 { 00230 return do_shutdown_send(_socket); 00231 }; 00232 00233 /* 00234 inline bool Socket_TCP::DoNotLinger() 00235 { 00236 int bOption = 1; 00237 if (setsockopt(_socket, SOL_SOCKET, SO_DONTLINGER, (const char *)&bOption, sizeof(bOption)) != 0) 00238 return false; 00239 return true; 00240 } 00241 */ 00242 00243 inline int Socket_TCP::SendData(const std::string &str) 00244 { 00245 return SendData(str.data(), str.size()); 00246 }; 00247 00248 #endif //__SOCKET_TCP_H__