Panda3D
socket_tcp.h
1 #ifndef __SOCKET_TCP_H__
2 #define __SOCKET_TCP_H__
3 
4 #include "pandabase.h"
5 #include "socket_ip.h"
6 
7 /////////////////////////////////////////////////////////////////////
8 // Class : Socket_TCP
9 //
10 // Description : Base functionality for a TCP connected socket
11 // This class is pretty useless by itself but it does hide some of the
12 // platform differences from machine to machine
13 //
14 /////////////////////////////////////////////////////////////////////
15 class EXPCL_PANDA_NATIVENET Socket_TCP : public Socket_IP
16 {
17 public:
18 PUBLISHED:
19  inline Socket_TCP(SOCKET);
20  inline Socket_TCP() { };
21  inline int SetNoDelay(bool flag = true);
22  inline int SetLinger(int interval_seconds = 0);
23  inline int DontLinger();
24  inline int SetSendBufferSize(int insize);
25  //inline bool ActiveOpen(const Socket_Address & theaddress);
26  inline bool ActiveOpen(const Socket_Address & theaddress, bool setdelay);
27  inline bool ActiveOpenNonBlocking(const Socket_Address & theaddress);
28  inline bool ErrorIs_WouldBlocking(int err);
29  inline bool ShutdownSend();
30  inline int SendData(const std::string &str);
31 // inline int RecvData( std::string &str, int max_len);
32 
33  std::string RecvData(int max_len);
34 public:
35  inline int SendData(const char * data, int size);
36  inline int RecvData(char * data, int size);
37 
38 public:
39  static TypeHandle get_class_type() {
40  return _type_handle;
41  }
42  static void init_type() {
43  Socket_IP::init_type();
44  register_type(_type_handle, "Socket_TCP",
45  Socket_IP::get_class_type());
46  }
47  virtual TypeHandle get_type() const {
48  return get_class_type();
49  }
50  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
51 
52 private:
53  static TypeHandle _type_handle;
54 };
55 
56 //////////////////////////////////////////////////////////////
57 // Function name : Socket_TCP::Socket_TCP
58 // Description :
59 //////////////////////////////////////////////////////////////
60 inline Socket_TCP::Socket_TCP(SOCKET sck) : ::Socket_IP(sck)
61 {
62 }
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function name : SetNoDelay
66 // Description : Disable Nagle algorithm. Don't delay send to coalesce packets
67 ////////////////////////////////////////////////////////////////////
68 inline int Socket_TCP::SetNoDelay(bool flag)
69 {
70  int nodel = flag;
71  int ret1;
72  ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel));
73 
74  if (ret1 != 0)
75  return BASIC_ERROR;
76 
77  return ALL_OK;
78 }
79 
80 ////////////////////////////////////////////////////////////////////
81 // Function name : SetLinger
82 // Description : will control the behavior of SO_LINGER for a TCP socket
83 ////////////////////////////////////////////////////////////////////
84 int Socket_TCP::SetLinger(int interval_seconds)
85 {
86  linger ll;
87  ll.l_linger = interval_seconds;
88  ll.l_onoff = 1;
89  int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
90  if (ret1 != 0)
91  return BASIC_ERROR;
92  return ALL_OK;
93 }
94 
95 ////////////////////////////////////////////////////////////////////
96 // Function name : Socket_TCP::DontLinger
97 // Description : Turn off the linger flag. The socket will quickly release
98 // buffered items and free up OS resources. You may lose
99 // a stream if you use this flag and do not negotiate the close
100 // at the application layer.
101 ////////////////////////////////////////////////////////////////////
103 {
104  linger ll;
105  ll.l_linger = 0;
106  ll.l_onoff = 0;
107  int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
108  if (ret1 != 0)
109  return BASIC_ERROR;
110  return ALL_OK;
111 }
112 
113 ////////////////////////////////////////////////////////////////////
114 // Function name : SetSendBufferSize
115 // Description : Just like it sounds. Sets a buffered socket recv buffer size.
116 // This function does not refuse ranges outside hard-coded OS
117 // limits
118 ////////////////////////////////////////////////////////////////////
120 {
121  if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_SNDBUF, (char *) &insize, sizeof(int)))
122  return BASIC_ERROR;
123  return ALL_OK;
124 }
125 
126 ////////////////////////////////////////////////////////////////////
127 // Function name : ActiveOpen
128 // Description : This function will try and set the socket up for active open to a specified
129 // address and port provided by the input parameter
130 ////////////////////////////////////////////////////////////////////
131 bool Socket_TCP::ActiveOpen(const Socket_Address & theaddress, bool setdelay)
132 {
133  _socket = DO_NEWTCP();
134  if (_socket == BAD_SOCKET)
135  return false;
136 
137  if(setdelay)
138  SetNoDelay();
139 
140  if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0)
141  return ErrorClose();
142 
143  return true;
144 }
145 
146 
147 ////////////////////////////////////////////////////////////////////
148 // Function name : ActiveOpenNonBlocking
149 // Description : This function will try and set the socket up for active open to a specified
150 // address and port provided by the input parameter (non-blocking version)
151 ////////////////////////////////////////////////////////////////////
153 {
154  _socket = DO_NEWTCP();
155  if (_socket == BAD_SOCKET)
156  return false;
157 
158  SetNonBlocking();
159  SetReuseAddress();
160 
161  if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0) {
162  if (GETERROR() != LOCAL_CONNECT_BLOCKING)
163  {
164  printf(" None Blockign Connect Error %d",GETERROR());
165  return ErrorClose();
166  }
167  }
168 
169  return true;
170 }
171 
172 ////////////////////////////////////////////////////////////////////
173 // Function name : Socket_TCP::SendData
174 // Description : Ok Lets Send the Data
175 //
176 // Return type : int
177 // - if error
178 // 0 if socket closed for write or lengh is 0
179 // + bytes writen ( May be smaller than requested)
180 ////////////////////////////////////////////////////////////////////
181 inline int Socket_TCP::SendData(const char * data, int size)
182 {
183  return DO_SOCKET_WRITE(_socket, data, size);
184 }
185 
186 ////////////////////////////////////////////////////////////////////
187 // Function name : Socket_TCP::RecvData
188 // Description : Read the data from the connection
189 //
190 // Return type : int
191 // - if error
192 // 0 if socket closed for read or length is 0
193 // + bytes read ( May be smaller than requested)
194 ////////////////////////////////////////////////////////////////////
195 inline int Socket_TCP::RecvData(char * data, int len)
196 {
197  int ecode = DO_SOCKET_READ(_socket, data, len);
198  return ecode;
199 }
200 
201 ////////////////////////////////////////////////////////////////////
202 // Function name : Socket_TCP::RecvData
203 // Description : Read the data from the connection
204 //
205 // Return type : int
206 // - if error
207 // 0 if socket closed for read or length is 0
208 // + bytes read ( May be smaller than requested)
209 ////////////////////////////////////////////////////////////////////
210 inline std::string Socket_TCP::RecvData(int max_len)
211 {
212  std::string str;
213  char *buffer = (char *) malloc(max_len+1);
214  int ecode = RecvData(buffer,max_len);
215  if(ecode > 0)
216  str.assign(buffer,ecode);
217 
218  free(buffer);
219  return str;
220 };
221 
222 
223 inline bool Socket_TCP::ErrorIs_WouldBlocking(int err)
224 {
225  return (GETERROR() == LOCAL_BLOCKING_ERROR);
226 }
227 
228 inline bool Socket_TCP::ShutdownSend()
229 {
230  return do_shutdown_send(_socket);
231 };
232 
233 /*
234 inline bool Socket_TCP::DoNotLinger()
235 {
236  int bOption = 1;
237  if (setsockopt(_socket, SOL_SOCKET, SO_DONTLINGER, (const char *)&bOption, sizeof(bOption)) != 0)
238  return false;
239  return true;
240 }
241 */
242 
243 inline int Socket_TCP::SendData(const std::string &str)
244 {
245  return SendData(str.data(), str.size());
246 };
247 
248 #endif //__SOCKET_TCP_H__
Base functionality for a TCP connected socket This class is pretty useless by itself but it does hide...
Definition: socket_tcp.h:15
Base functionality for a INET domain Socket this call should be the starting point for all other unix...
Definition: socket_ip.h:34
int SetNonBlocking()
this function will throw a socket into non-blocking mode
Definition: socket_ip.h:183
std::string RecvData(int max_len)
Read the data from the connection.
Definition: socket_tcp.h:210
bool ActiveOpenNonBlocking(const Socket_Address &theaddress)
This function will try and set the socket up for active open to a specified address and port provided...
Definition: socket_tcp.h:152
int DontLinger()
Turn off the linger flag.
Definition: socket_tcp.h:102
A simple place to store and munipulate tcp and port address for communication layer.
int SetLinger(int interval_seconds=0)
will control the behavior of SO_LINGER for a TCP socket
Definition: socket_tcp.h:84
Socket_IP()
Def Constructor.
Definition: socket_ip.h:114
bool SetReuseAddress(bool flag=true)
Informs a socket to reuse IP address as needed.
Definition: socket_ip.h:228
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
bool ActiveOpen(const Socket_Address &theaddress, bool setdelay)
This function will try and set the socket up for active open to a specified address and port provided...
Definition: socket_tcp.h:131
int SetSendBufferSize(int insize)
Just like it sounds.
Definition: socket_tcp.h:119
int SetNoDelay(bool flag=true)
Disable Nagle algorithm.
Definition: socket_tcp.h:68