libsocket 1.5
|
00001 /* 00002 ** tcpsocket.cc 00003 ** Login : Julien Lemoine <speedblue@happycoders.org> 00004 ** Started on Sun Mar 2 01:18:46 2003 Julien Lemoine 00005 ** $Id: tcpsocket.cc,v 1.6 2004/11/14 19:37:46 speedblue Exp $ 00006 ** 00007 ** Copyright (C) 2003,2004 Julien Lemoine 00008 ** This program is free software; you can redistribute it and/or modify 00009 ** it under the terms of the GNU Lesser General Public License as published by 00010 ** the Free Software Foundation; either version 2 of the License, or 00011 ** (at your option) any later version. 00012 ** 00013 ** This program is distributed in the hope that it will be useful, 00014 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 ** GNU Lesser General Public License for more details. 00017 ** 00018 ** You should have received a copy of the GNU Lesser General Public License 00019 ** along with this program; if not, write to the Free Software 00020 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 */ 00022 00023 #include "tcpsocket.hh" 00024 00025 namespace Network 00026 { 00027 00028 void TcpSocket::connect(const std::string& hostname, int port) 00029 { 00030 _port = port; 00031 _socket = _bind(port, hostname); 00032 _connect(_socket, port, hostname); 00033 } 00034 00035 void TcpSocket::connect(int port) 00036 { 00037 _port = port; 00038 _socket = _bind(port); 00039 _listen(_socket); 00040 } 00041 00042 TcpSocket* TcpSocket::accept() const 00043 { 00044 TcpSocket* res; 00045 00046 #ifdef IPV6_ENABLED 00047 if (V4 == _version) 00048 #endif 00049 res = new TcpSocket(_accept(_port, _socket)); 00050 #ifdef IPV6_ENABLED 00051 else 00052 res = new TcpSocket(_accept(_port, _socket), V6); 00053 #endif 00054 res->_port = _port; 00055 res->_proto_kind = _proto_kind; 00056 #ifdef TLS 00057 if (_tls) 00058 { 00059 res->_tls = true; 00060 res->_tls_main = false; 00061 res->_session = _session; 00062 res->_x509_cred = _x509_cred; 00063 res->enable_tls(); 00064 } 00065 #endif 00066 return res; 00067 } 00068 00069 std::string TcpSocket::get_ip(TcpSocket *client) const 00070 { 00071 return _get_ip(_port, client->_socket); 00072 } 00073 00074 void TcpSocket::close() 00075 { 00076 if (_socket > 0) 00077 _close(_socket); 00078 _socket = 0; 00079 } 00080 00081 std::string TcpSocket::_read_line_bin(int socket, unsigned int psize) 00082 { 00083 char chr[MAXPKTSIZE]; 00084 std::string str = ""; 00085 int res = 1; 00086 unsigned int size = 0, read = 0; 00087 bool end = false; 00088 00089 if (socket < 0) 00090 throw NoConnection("No Socket", HERE); 00091 if (_buffer.size() >= 2 && !psize) 00092 { 00093 size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1]; 00094 str = _buffer.substr(2, size); 00095 if (_buffer.size() > size + 2) 00096 _buffer = _buffer.substr(size + 2, _buffer.size() - size - 2); 00097 else 00098 _buffer = ""; 00099 read = str.size(); 00100 } 00101 if (psize && _buffer.size() >= psize) 00102 { 00103 str = _buffer.substr(0, psize); 00104 _buffer = _buffer.substr(psize, _buffer.size() - psize); 00105 return str; 00106 } 00107 else if (!psize) 00108 { 00109 // _buffer.size() is 0 or 1 00110 #ifdef TLS 00111 if (_tls) 00112 res = gnutls_record_recv(_session, chr, 2 - _buffer.size()); 00113 else 00114 #endif 00115 res = recv(socket, chr, 2 - _buffer.size(), 0); 00116 if (res <= 1) 00117 throw ConnectionClosed("Connection Closed", HERE); 00118 if (_buffer.size()) 00119 size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0]; 00120 else 00121 size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1]; 00122 _buffer = ""; 00123 } 00124 else 00125 { 00126 // _buffer contains less characters than size, so copy 00127 // _bufer in str and clear _buffer. 00128 str = _buffer; 00129 _buffer = ""; 00130 size = psize; 00131 read = str.size(); 00132 } 00133 while (!end) 00134 { 00135 memset(chr, 0, MAXPKTSIZE); 00136 #ifdef TLS 00137 if (_tls) 00138 res = gnutls_record_recv(_session, chr, size - read); 00139 else 00140 #endif 00141 res = recv(socket, chr, size - read, 0); 00142 if (res <= 0) 00143 throw ConnectionClosed("Connection Closed", HERE); 00144 str += std::string(chr, res).substr(0, res); 00145 read += res; 00146 if (read >= size) 00147 end = true; 00148 } 00149 return str; 00150 } 00151 00152 std::string TcpSocket::_read_line_bin(int socket, int& port, 00153 std::string& host, 00154 unsigned int psize) 00155 { 00156 char chr[MAXPKTSIZE]; 00157 std::string str = ""; 00158 int res = 1; 00159 struct sockaddr_in addr; 00160 #ifdef IPV6_ENABLED 00161 struct sockaddr_in6 addr6; 00162 #endif 00163 #ifdef LIBSOCKET_WIN 00164 int size; 00165 #else 00166 socklen_t size; 00167 #endif 00168 bool end = false; 00169 unsigned int pkg_size = 0, read = 0; 00170 00171 #ifdef IPV6_ENABLED 00172 if (V4 == _version) 00173 #endif 00174 size = sizeof(addr); 00175 #ifdef IPV6_ENABLED 00176 else 00177 size = sizeof(addr6); 00178 #endif 00179 if (socket < 0) 00180 throw NoConnection("No Socket", HERE); 00181 if (_buffer.size() >= 2 && !psize) 00182 { 00183 pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1]; 00184 str = _buffer.substr(2, pkg_size); 00185 if (_buffer.size() > pkg_size + 2) 00186 _buffer = _buffer.substr(pkg_size + 2, _buffer.size() - pkg_size - 2); 00187 else 00188 _buffer = ""; 00189 read = str.size(); 00190 } 00191 if (psize && _buffer.size() >= psize) 00192 { 00193 str = _buffer.substr(0, psize); 00194 _buffer = _buffer.substr(psize, _buffer.size() - psize); 00195 return str; 00196 } 00197 else if (!psize) 00198 { 00199 // _buffer.size() is 0 or 1 00200 #ifdef TLS 00201 if (_tls) 00202 res = gnutls_record_recv(_session, chr, 2 - _buffer.size()); 00203 else 00204 #endif 00205 res = recv(socket, chr, 2 - _buffer.size(), 0); 00206 if (res <= 1) 00207 throw ConnectionClosed("Connection Closed", HERE); 00208 if (_buffer.size()) 00209 pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0]; 00210 else 00211 pkg_size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1]; 00212 _buffer = ""; 00213 } 00214 else 00215 { 00216 // _buffer contains less characters than size, so copy 00217 // _bufer in str and clear _buffer. 00218 str = _buffer; 00219 _buffer = ""; 00220 pkg_size = psize; 00221 read = str.size(); 00222 } 00223 while (!end) 00224 { 00225 #ifdef TLS 00226 if (_tls) 00227 res = gnutls_record_recv(_session, chr, size - read); 00228 else 00229 #endif 00230 res = recv(socket, chr, size - read, 0); 00231 #ifdef IPV6_ENABLED 00232 if (V4 == _version) 00233 #endif 00234 if (getpeername(socket, (struct sockaddr *) &addr, &size) < 0) 00235 throw GetpeernameError("getpeername error", HERE); 00236 #ifdef IPV6_ENABLED 00237 else 00238 if (getpeername(socket, (struct sockaddr *) &addr6, &size) < 0) 00239 throw GetpeernameError("getpeername error", HERE); 00240 #endif 00241 if (res <= 0) 00242 throw ConnectionClosed("Connection Closed", HERE); 00243 str += std::string(chr, res).substr(0, res); 00244 read += res; 00245 if (read >= pkg_size) 00246 end = true; 00247 } 00248 #ifdef IPV6_ENABLED 00249 if (V4 == _version) 00250 { 00251 #endif 00252 host = std::string(inet_ntoa(addr.sin_addr)); 00253 port = ntohs(addr.sin_port); 00254 #ifdef IPV6_ENABLED 00255 } 00256 else 00257 { 00258 char buf[INET6_ADDRSTRLEN]; 00259 if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0) 00260 throw InetntopError("Not a valid address", HERE); 00261 host = std::string(buf); 00262 port = ntohs(addr6.sin6_port); 00263 } 00264 #endif 00265 return str; 00266 } 00267 }