libsocket  1.5
udpsocket.cc
Go to the documentation of this file.
1 /*
2 ** udpsocket.cc
3 ** Login : Julien Lemoine <speedblue@happycoders.org>
4 ** Started on Sun Mar 2 01:01:49 2003 Julien Lemoine
5 ** $Id: udpsocket.cc,v 1.3 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 "udpsocket.hh"
24 
25 namespace Network
26 {
27  void UdpSocket::connect(const std::string& hostname, int port)
28  {
29  _port = port;
30  _socket = _bind(port, hostname);
31  }
32 
33  void UdpSocket::connect(int port)
34  {
35  _socket = _bind(port);
36  _port = port;
37  }
38 
40  {
41  if (_socket > 0)
42  _close(_socket);
43  _socket = 0;
44  }
45 
46  std::string UdpSocket::_read_line_bin(int socket, unsigned int size)
47  {
48  char chr[MAXPKTSIZE];
49  std::string str = "";
50  int res = 1;
51  bool end = false;
52 
53  if (socket < 0)
54  throw NoConnection("No Socket", HERE);
55  if (_buffer.size() >= 2 && !size)
56  {
57  size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
58  _buffer = _buffer.substr(2, _buffer.size() - 2);
59  }
60  if (size && _buffer.size() >= size)
61  {
62  str = _buffer.substr(0, size);
63  _buffer = _buffer.substr(size, _buffer.size() - size);
64  }
65  else
66  while (!end)
67  {
68  memset(chr, 0, MAXPKTSIZE);
69 #ifdef LIBSOCKET_WIN
70  res = recv(socket, chr, MAXPKTSIZE, 0);
71 #else
72  res = recv(socket, chr, MAXPKTSIZE, MSG_TRUNC);
73 #endif
74  if (res <= 0)
75  throw ConnectionClosed("Connection Closed", HERE);
76  // _buffer += all octets received
77  _buffer += std::string(chr, res);
78  if (!size)
79  {
80  // extract size from _buffer and reduce it
81  size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
82  _buffer = _buffer.substr(2, _buffer.size() - 2);
83  }
84  if (_buffer.size() > size - str.size())
85  {
86  str += _buffer.substr(0, size - str.size());
87  _buffer = _buffer.substr(size - str.size(),
88  _buffer.size() - size - str.size());
89  }
90  else
91  {
92  str += _buffer;
93  _buffer = "";
94  }
95  if (str.size() >= size)
96  end = true;
97  }
98  return str;
99  }
100 
101  std::string UdpSocket::_read_line_bin(int socket, int& port,
102  std::string& host,
103  unsigned int pkg_size)
104  {
105  char chr[MAXPKTSIZE];
106  std::string str = "";
107  int res = 1;
108  struct sockaddr_in addr;
109 #ifdef IPV6_ENABLED
110  struct sockaddr_in6 addr6;
111 #endif
112 #ifdef LIBSOCKET_WIN
113  int size;
114 #else
115  socklen_t size;
116 #endif
117  bool end = false;
118 
119 #ifdef IPV6_ENABLED
120  if (V4 == _version)
121 #endif
122  size = sizeof(addr);
123 #ifdef IPV6_ENABLED
124  else
125  size = sizeof(addr6);
126 #endif
127  if (socket < 0)
128  throw NoConnection("No Socket", HERE);
129  if (_buffer.size() >= 2 && !pkg_size)
130  {
131  pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
132  _buffer = _buffer.substr(2, _buffer.size() - 2);
133  }
134  if (pkg_size && _buffer.size() >= pkg_size)
135  {
136  str = _buffer.substr(0, pkg_size);
137  _buffer = _buffer.substr(pkg_size, _buffer.size() - pkg_size);
138  }
139  else
140  while (!end)
141  {
142 #ifdef LIBSOCKET_WIN
143  int flags = 0;
144 #else
145  int flags = MSG_TRUNC;
146 #endif
147 #ifdef IPV6_ENABLED
148  if (V4 == _version)
149 #endif
150  res = recvfrom(socket, chr, MAXPKTSIZE, flags,
151  (struct sockaddr *) &addr, &size);
152 #ifdef IPV6_ENABLED
153  else
154  res = recvfrom(socket, chr, MAXPKTSIZE, flags,
155  (struct sockaddr *) &addr6, &size);
156 #endif
157  if (res <= 0)
158  throw ConnectionClosed("Connection Closed", HERE);
159  // _buffer += all octets received
160  _buffer += std::string(chr, res).substr(0, res);
161  if (!pkg_size)
162  {
163  // extract size from _buffer and reduce it
164  pkg_size = (unsigned char)_buffer[0] * 256 +
165  (unsigned char)_buffer[1];
166  _buffer = _buffer.substr(2, _buffer.size() - 2);
167  }
168  if (_buffer.size() > pkg_size - str.size())
169  {
170  str += _buffer.substr(0, pkg_size - str.size());
171  _buffer = _buffer.substr(pkg_size - str.size(),
172  _buffer.size() - pkg_size - str.size());
173  }
174  else
175  {
176  str += _buffer;
177  _buffer = "";
178  }
179  if (str.size() >= pkg_size)
180  end = true;
181  }
182 #ifdef IPV6_ENABLED
183  if (V4 == _version)
184  {
185 #endif
186  host = std::string(inet_ntoa(addr.sin_addr));
187  port = ntohs(addr.sin_port);
188 #ifdef IPV6_ENABLED
189  }
190  else
191  {
192  char buf[INET6_ADDRSTRLEN];
193  if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0)
194  throw InetntopError("Not a valid address", HERE);
195  host = std::string(buf);
196  port = ntohs(addr6.sin6_port);
197  }
198 #endif
199  return str;
200  }
201 
202 }
udpsocket.hh
Network::Socket::_buffer
std::string _buffer
Definition: socket.hh:202
Network
Network namespace represent all networks connection.
Definition: localsocket.cc:32
Network::Socket::_version
SOCKET_VERSION _version
Definition: socket.hh:191
Network::UdpSocket::close
void close()
Close the connection.
Definition: udpsocket.cc:39
Network::NetSocket::_port
int _port
Definition: netsocket.hh:161
Network::V4
@ V4
Definition: socket.hh:87
HERE
#define HERE
Definition: socketexception.hh:26
Network::UdpSocket::connect
void connect(const std::string &hostname, int port)
Connect as an UDP client.
Definition: udpsocket.cc:27
Network::Socket::_socket
int _socket
Definition: socket.hh:193
Network::NetSocket::_bind
int _bind(int port, const std::string &host)
Bind a UDP server.
Definition: netsocket.cc:86
Network::UdpSocket::_read_line_bin
std::string _read_line_bin(int socket, int &port, std::string &host, unsigned int pkg_size)
Get a line from socket and store client hostname and port in port and host variable (when used with b...
Definition: udpsocket.cc:101
Network::Socket::_close
void _close(int socket) const
Close a connnection.
Definition: socket.cc:167