00001 #ifndef __SOCKET_TCP_H__
00002 #define __SOCKET_TCP_H__
00003
00004 #include "pandabase.h"
00005 #include "socket_ip.h"
00006
00007
00008
00009
00010
00011
00012
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
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
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
00058
00059
00060 inline Socket_TCP::Socket_TCP(SOCKET sck) : ::Socket_IP(sck)
00061 {
00062 }
00063
00064
00065
00066
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
00082
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
00097
00098
00099
00100
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
00115
00116
00117
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
00128
00129
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
00149
00150
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
00174
00175
00176
00177
00178
00179
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
00188
00189
00190
00191
00192
00193
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
00203
00204
00205
00206
00207
00208
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
00235
00236
00237
00238
00239
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__