libsocket  1.5
tcpsocket.cc
Go to the documentation of this file.
1 /*
2 ** tcpsocket.cc
3 ** Login : Julien Lemoine <speedblue@happycoders.org>
4 ** Started on Sun Mar 2 01:18:46 2003 Julien Lemoine
5 ** $Id: tcpsocket.cc,v 1.6 2004/11/14 19:37:46 speedblue Exp $
6 **
7 ** Copyright (C) 2003,2004 Julien Lemoine
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU Lesser General Public License as published by
10 ** the Free Software Foundation; either version 2 of the License, or
11 ** (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU Lesser General Public License for more details.
17 **
18 ** You should have received a copy of the GNU Lesser General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22 
23 #include "tcpsocket.hh"
24 
25 namespace Network
26 {
27 
28  void TcpSocket::connect(const std::string& hostname, int port)
29  {
30  _port = port;
31  _socket = _bind(port, hostname);
32  _connect(_socket, port, hostname);
33  }
34 
35  void TcpSocket::connect(int port)
36  {
37  _port = port;
38  _socket = _bind(port);
40  }
41 
43  {
44  TcpSocket* res;
45 
46 #ifdef IPV6_ENABLED
47  if (V4 == _version)
48 #endif
49  res = new TcpSocket(_accept(_port, _socket));
50 #ifdef IPV6_ENABLED
51  else
52  res = new TcpSocket(_accept(_port, _socket), V6);
53 #endif
54  res->_port = _port;
55  res->_proto_kind = _proto_kind;
56 #ifdef TLS
57  if (_tls)
58  {
59  res->_tls = true;
60  res->_tls_main = false;
61  res->_session = _session;
62  res->_x509_cred = _x509_cred;
63  res->enable_tls();
64  }
65 #endif
66  return res;
67  }
68 
69  std::string TcpSocket::get_ip(TcpSocket *client) const
70  {
71  return _get_ip(_port, client->_socket);
72  }
73 
75  {
76  if (_socket > 0)
77  _close(_socket);
78  _socket = 0;
79  }
80 
81  std::string TcpSocket::_read_line_bin(int socket, unsigned int psize)
82  {
83  char chr[MAXPKTSIZE];
84  std::string str = "";
85  int res = 1;
86  unsigned int size = 0, read = 0;
87  bool end = false;
88 
89  if (socket < 0)
90  throw NoConnection("No Socket", HERE);
91  if (_buffer.size() >= 2 && !psize)
92  {
93  size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
94  str = _buffer.substr(2, size);
95  if (_buffer.size() > size + 2)
96  _buffer = _buffer.substr(size + 2, _buffer.size() - size - 2);
97  else
98  _buffer = "";
99  read = str.size();
100  }
101  if (psize && _buffer.size() >= psize)
102  {
103  str = _buffer.substr(0, psize);
104  _buffer = _buffer.substr(psize, _buffer.size() - psize);
105  return str;
106  }
107  else if (!psize)
108  {
109  // _buffer.size() is 0 or 1
110 #ifdef TLS
111  if (_tls)
112  res = gnutls_record_recv(_session, chr, 2 - _buffer.size());
113  else
114 #endif
115  res = recv(socket, chr, 2 - _buffer.size(), 0);
116  if (res <= 1)
117  throw ConnectionClosed("Connection Closed", HERE);
118  if (_buffer.size())
119  size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0];
120  else
121  size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1];
122  _buffer = "";
123  }
124  else
125  {
126  // _buffer contains less characters than size, so copy
127  // _bufer in str and clear _buffer.
128  str = _buffer;
129  _buffer = "";
130  size = psize;
131  read = str.size();
132  }
133  while (!end)
134  {
135  memset(chr, 0, MAXPKTSIZE);
136 #ifdef TLS
137  if (_tls)
138  res = gnutls_record_recv(_session, chr, size - read);
139  else
140 #endif
141  res = recv(socket, chr, size - read, 0);
142  if (res <= 0)
143  throw ConnectionClosed("Connection Closed", HERE);
144  str += std::string(chr, res).substr(0, res);
145  read += res;
146  if (read >= size)
147  end = true;
148  }
149  return str;
150  }
151 
152  std::string TcpSocket::_read_line_bin(int socket, int& port,
153  std::string& host,
154  unsigned int psize)
155  {
156  char chr[MAXPKTSIZE];
157  std::string str = "";
158  int res = 1;
159  struct sockaddr_in addr;
160 #ifdef IPV6_ENABLED
161  struct sockaddr_in6 addr6;
162 #endif
163 #ifdef LIBSOCKET_WIN
164  int size;
165 #else
166  socklen_t size;
167 #endif
168  bool end = false;
169  unsigned int pkg_size = 0, read = 0;
170 
171 #ifdef IPV6_ENABLED
172  if (V4 == _version)
173 #endif
174  size = sizeof(addr);
175 #ifdef IPV6_ENABLED
176  else
177  size = sizeof(addr6);
178 #endif
179  if (socket < 0)
180  throw NoConnection("No Socket", HERE);
181  if (_buffer.size() >= 2 && !psize)
182  {
183  pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
184  str = _buffer.substr(2, pkg_size);
185  if (_buffer.size() > pkg_size + 2)
186  _buffer = _buffer.substr(pkg_size + 2, _buffer.size() - pkg_size - 2);
187  else
188  _buffer = "";
189  read = str.size();
190  }
191  if (psize && _buffer.size() >= psize)
192  {
193  str = _buffer.substr(0, psize);
194  _buffer = _buffer.substr(psize, _buffer.size() - psize);
195  return str;
196  }
197  else if (!psize)
198  {
199  // _buffer.size() is 0 or 1
200 #ifdef TLS
201  if (_tls)
202  res = gnutls_record_recv(_session, chr, 2 - _buffer.size());
203  else
204 #endif
205  res = recv(socket, chr, 2 - _buffer.size(), 0);
206  if (res <= 1)
207  throw ConnectionClosed("Connection Closed", HERE);
208  if (_buffer.size())
209  pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0];
210  else
211  pkg_size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1];
212  _buffer = "";
213  }
214  else
215  {
216  // _buffer contains less characters than size, so copy
217  // _bufer in str and clear _buffer.
218  str = _buffer;
219  _buffer = "";
220  pkg_size = psize;
221  read = str.size();
222  }
223  while (!end)
224  {
225 #ifdef TLS
226  if (_tls)
227  res = gnutls_record_recv(_session, chr, size - read);
228  else
229 #endif
230  res = recv(socket, chr, size - read, 0);
231 #ifdef IPV6_ENABLED
232  if (V4 == _version)
233 #endif
234  if (getpeername(socket, (struct sockaddr *) &addr, &size) < 0)
235  throw GetpeernameError("getpeername error", HERE);
236 #ifdef IPV6_ENABLED
237  else
238  if (getpeername(socket, (struct sockaddr *) &addr6, &size) < 0)
239  throw GetpeernameError("getpeername error", HERE);
240 #endif
241  if (res <= 0)
242  throw ConnectionClosed("Connection Closed", HERE);
243  str += std::string(chr, res).substr(0, res);
244  read += res;
245  if (read >= pkg_size)
246  end = true;
247  }
248 #ifdef IPV6_ENABLED
249  if (V4 == _version)
250  {
251 #endif
252  host = std::string(inet_ntoa(addr.sin_addr));
253  port = ntohs(addr.sin_port);
254 #ifdef IPV6_ENABLED
255  }
256  else
257  {
258  char buf[INET6_ADDRSTRLEN];
259  if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0)
260  throw InetntopError("Not a valid address", HERE);
261  host = std::string(buf);
262  port = ntohs(addr6.sin6_port);
263  }
264 #endif
265  return str;
266  }
267 }
TcpSocket * accept() const
accept a new client (For server only)
Definition: tcpsocket.cc:42
void _close(int socket) const
Close a connnection when close libc function return a negative value.
Definition: socket.cc:167
void enable_tls()
Enable TLS on socket.
Definition: socket.cc:69
std::string _read_line_bin(int socket, int &port, std::string &host, unsigned int psize)
Get a line from socket and store client hostname and port in port and host variable (when used with b...
Definition: tcpsocket.cc:152
Network namespace represent all networks connection.
Definition: localsocket.cc:32
void close()
Close the connection.
Definition: tcpsocket.cc:74
void connect(const std::string &hostname, int port)
Connect as an TCP client.
Definition: tcpsocket.cc:28
void _connect(int socket, int port, const std::string &host) const
Connect to a hostname when connect libc function return a negative value.
Definition: netsocket.cc:186
std::string _buffer
Definition: socket.hh:202
TcpSocket(SOCKET_VERSION version=V4)
Definition: tcpsocket.hh:35
void _listen(int socket) const
Listen on port when listen libc function return a negative value.
Definition: socket.cc:192
PROTO_KIND _proto_kind
Definition: socket.hh:199
std::string read()
function used by >> operator (read a string on current socket)
Definition: netsocket.cc:533
SOCKET_VERSION _version
Definition: socket.hh:191
#define HERE
std::string get_ip(TcpSocket *client) const
return ip of client (after an accept)
Definition: tcpsocket.cc:69
std::string _get_ip(int port, int socket) const
Get Client Ip.
Definition: netsocket.cc:243
int _accept(int port, int server_socket) const
Wait for a client when accept libc function return a negative value.
Definition: netsocket.cc:211
int _bind(int port, const std::string &host)
Bind a UDP server when socket libc function return a negative value if the selected protocole is inco...
Definition: netsocket.cc:86
This class represent a tcp connection (client and server)
Definition: tcpsocket.hh:32