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
25namespace 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;
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)
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}
int _bind(int port, const std::string &host)
Bind a UDP server.
Definition netsocket.cc:86
std::string _get_ip(int port, int socket) const
Get Client Ip.
Definition netsocket.cc:243
void _connect(int socket, int port, const std::string &host) const
Connect to a hostname.
Definition netsocket.cc:186
int _accept(int port, int server_socket) const
Wait for a client.
Definition netsocket.cc:211
std::string read()
function used by >> operator (read a string on current socket)
Definition netsocket.cc:533
std::string _buffer
Definition socket.hh:202
void enable_tls()
Enable TLS on socket.
Definition socket.cc:69
SOCKET_VERSION _version
Definition socket.hh:191
void _listen(int socket) const
Listen on port.
Definition socket.cc:192
void _close(int socket) const
Close a connnection.
Definition socket.cc:167
PROTO_KIND _proto_kind
Definition socket.hh:199
This class represent a tcp connection (client and server)
Definition tcpsocket.hh:33
std::string get_ip(TcpSocket *client) const
return ip of client (after an accept)
Definition tcpsocket.cc:69
void close()
Close the connection.
Definition tcpsocket.cc:74
TcpSocket * accept() const
accept a new client (For server only)
Definition tcpsocket.cc:42
void connect(const std::string &hostname, int port)
Connect as an TCP client.
Definition tcpsocket.cc:28
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.
#define HERE