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