libsocket 1.5
|
00001 /* 00002 ** udpsocket.cc 00003 ** Login : Julien Lemoine <speedblue@happycoders.org> 00004 ** Started on Sun Mar 2 01:01:49 2003 Julien Lemoine 00005 ** $Id: udpsocket.cc,v 1.3 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 "udpsocket.hh" 00024 00025 namespace Network 00026 { 00027 void UdpSocket::connect(const std::string& hostname, int port) 00028 { 00029 _port = port; 00030 _socket = _bind(port, hostname); 00031 } 00032 00033 void UdpSocket::connect(int port) 00034 { 00035 _socket = _bind(port); 00036 _port = port; 00037 } 00038 00039 void UdpSocket::close() 00040 { 00041 if (_socket > 0) 00042 _close(_socket); 00043 _socket = 0; 00044 } 00045 00046 std::string UdpSocket::_read_line_bin(int socket, unsigned int size) 00047 { 00048 char chr[MAXPKTSIZE]; 00049 std::string str = ""; 00050 int res = 1; 00051 bool end = false; 00052 00053 if (socket < 0) 00054 throw NoConnection("No Socket", HERE); 00055 if (_buffer.size() >= 2 && !size) 00056 { 00057 size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1]; 00058 _buffer = _buffer.substr(2, _buffer.size() - 2); 00059 } 00060 if (size && _buffer.size() >= size) 00061 { 00062 str = _buffer.substr(0, size); 00063 _buffer = _buffer.substr(size, _buffer.size() - size); 00064 } 00065 else 00066 while (!end) 00067 { 00068 memset(chr, 0, MAXPKTSIZE); 00069 #ifdef LIBSOCKET_WIN 00070 res = recv(socket, chr, MAXPKTSIZE, 0); 00071 #else 00072 res = recv(socket, chr, MAXPKTSIZE, MSG_TRUNC); 00073 #endif 00074 if (res <= 0) 00075 throw ConnectionClosed("Connection Closed", HERE); 00076 // _buffer += all octets received 00077 _buffer += std::string(chr, res); 00078 if (!size) 00079 { 00080 // extract size from _buffer and reduce it 00081 size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1]; 00082 _buffer = _buffer.substr(2, _buffer.size() - 2); 00083 } 00084 if (_buffer.size() > size - str.size()) 00085 { 00086 str += _buffer.substr(0, size - str.size()); 00087 _buffer = _buffer.substr(size - str.size(), 00088 _buffer.size() - size - str.size()); 00089 } 00090 else 00091 { 00092 str += _buffer; 00093 _buffer = ""; 00094 } 00095 if (str.size() >= size) 00096 end = true; 00097 } 00098 return str; 00099 } 00100 00101 std::string UdpSocket::_read_line_bin(int socket, int& port, 00102 std::string& host, 00103 unsigned int pkg_size) 00104 { 00105 char chr[MAXPKTSIZE]; 00106 std::string str = ""; 00107 int res = 1; 00108 struct sockaddr_in addr; 00109 #ifdef IPV6_ENABLED 00110 struct sockaddr_in6 addr6; 00111 #endif 00112 #ifdef LIBSOCKET_WIN 00113 int size; 00114 #else 00115 socklen_t size; 00116 #endif 00117 bool end = false; 00118 00119 #ifdef IPV6_ENABLED 00120 if (V4 == _version) 00121 #endif 00122 size = sizeof(addr); 00123 #ifdef IPV6_ENABLED 00124 else 00125 size = sizeof(addr6); 00126 #endif 00127 if (socket < 0) 00128 throw NoConnection("No Socket", HERE); 00129 if (_buffer.size() >= 2 && !pkg_size) 00130 { 00131 pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1]; 00132 _buffer = _buffer.substr(2, _buffer.size() - 2); 00133 } 00134 if (pkg_size && _buffer.size() >= pkg_size) 00135 { 00136 str = _buffer.substr(0, pkg_size); 00137 _buffer = _buffer.substr(pkg_size, _buffer.size() - pkg_size); 00138 } 00139 else 00140 while (!end) 00141 { 00142 #ifdef LIBSOCKET_WIN 00143 int flags = 0; 00144 #else 00145 int flags = MSG_TRUNC; 00146 #endif 00147 #ifdef IPV6_ENABLED 00148 if (V4 == _version) 00149 #endif 00150 res = recvfrom(socket, chr, MAXPKTSIZE, flags, 00151 (struct sockaddr *) &addr, &size); 00152 #ifdef IPV6_ENABLED 00153 else 00154 res = recvfrom(socket, chr, MAXPKTSIZE, flags, 00155 (struct sockaddr *) &addr6, &size); 00156 #endif 00157 if (res <= 0) 00158 throw ConnectionClosed("Connection Closed", HERE); 00159 // _buffer += all octets received 00160 _buffer += std::string(chr, res).substr(0, res); 00161 if (!pkg_size) 00162 { 00163 // extract size from _buffer and reduce it 00164 pkg_size = (unsigned char)_buffer[0] * 256 + 00165 (unsigned char)_buffer[1]; 00166 _buffer = _buffer.substr(2, _buffer.size() - 2); 00167 } 00168 if (_buffer.size() > pkg_size - str.size()) 00169 { 00170 str += _buffer.substr(0, pkg_size - str.size()); 00171 _buffer = _buffer.substr(pkg_size - str.size(), 00172 _buffer.size() - pkg_size - str.size()); 00173 } 00174 else 00175 { 00176 str += _buffer; 00177 _buffer = ""; 00178 } 00179 if (str.size() >= pkg_size) 00180 end = true; 00181 } 00182 #ifdef IPV6_ENABLED 00183 if (V4 == _version) 00184 { 00185 #endif 00186 host = std::string(inet_ntoa(addr.sin_addr)); 00187 port = ntohs(addr.sin_port); 00188 #ifdef IPV6_ENABLED 00189 } 00190 else 00191 { 00192 char buf[INET6_ADDRSTRLEN]; 00193 if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0) 00194 throw InetntopError("Not a valid address", HERE); 00195 host = std::string(buf); 00196 port = ntohs(addr6.sin6_port); 00197 } 00198 #endif 00199 return str; 00200 } 00201 00202 }