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
25namespace 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)
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}
int _bind(int port, const std::string &host)
Bind a UDP server.
Definition netsocket.cc:86
std::string _buffer
Definition socket.hh:202
SOCKET_VERSION _version
Definition socket.hh:191
void _close(int socket) const
Close a connnection.
Definition socket.cc:167
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
void connect(const std::string &hostname, int port)
Connect as an UDP client.
Definition udpsocket.cc:27
void close()
Close the connection.
Definition udpsocket.cc:39
Network namespace represent all networks connection.
#define HERE