Mercurial > code
annotate C++/Socket.cpp @ 259:0b3fcc5ed8eb
Socket: forget to add address in recvfrom
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 05 Oct 2014 11:48:39 +0200 |
parents | 4ad3c85ab73e |
children | 2096edb63a4f |
rev | line source |
---|---|
170 | 1 /* |
2 * Socket.cpp -- portable C++ socket wrappers | |
3 * | |
4 * Copyright (c) 2013, David Demelier <markand@malikania.fr> | |
5 * | |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
176
ba62ab219fc4
add cstring for strerror
David Demelier <markand@malikania.fr>
parents:
175
diff
changeset
|
19 #include <cstring> |
170 | 20 |
21 #include "Socket.h" | |
22 #include "SocketAddress.h" | |
23 | |
24 /* -------------------------------------------------------- | |
258 | 25 * Socket exceptions |
170 | 26 * -------------------------------------------------------- */ |
27 | |
258 | 28 namespace error { |
29 | |
30 const char *Timeout::what() const noexcept | |
170 | 31 { |
258 | 32 return "Timeout exception"; |
170 | 33 } |
34 | |
258 | 35 const char *InProgress::what() const noexcept |
170 | 36 { |
258 | 37 return "Operation in progress"; |
170 | 38 } |
39 | |
258 | 40 const char *WouldBlock::what() const noexcept |
41 { | |
42 return "Operation would block"; | |
43 } | |
44 | |
45 } // !error | |
46 | |
170 | 47 /* -------------------------------------------------------- |
48 * Socket implementation | |
49 * -------------------------------------------------------- */ | |
50 | |
51 void Socket::init() | |
52 { | |
53 #if defined(_WIN32) | |
54 WSADATA wsa; | |
55 WSAStartup(MAKEWORD(2, 2), &wsa); | |
56 #endif | |
57 } | |
58 | |
258 | 59 void Socket::finish() |
60 { | |
61 #if defined(_WIN32) | |
62 WSACleanup(); | |
63 #endif | |
64 } | |
65 | |
170 | 66 /* -------------------------------------------------------- |
67 * System dependent code | |
68 * -------------------------------------------------------- */ | |
69 | |
70 #if defined(_WIN32) | |
71 | |
258 | 72 std::string Socket::syserror(int errn) |
170 | 73 { |
74 LPSTR str = nullptr; | |
188
ce3e1c3d6fed
Update sockets to style and using instead of typedef
David Demelier <markand@malikania.fr>
parents:
176
diff
changeset
|
75 std::string errmsg = "Unknown error"; |
170 | 76 |
77 FormatMessageA( | |
78 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, | |
79 NULL, | |
258 | 80 errn, |
170 | 81 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
82 (LPSTR)&str, 0, NULL); | |
83 | |
84 | |
188
ce3e1c3d6fed
Update sockets to style and using instead of typedef
David Demelier <markand@malikania.fr>
parents:
176
diff
changeset
|
85 if (str) { |
170 | 86 errmsg = string(str); |
87 LocalFree(str); | |
88 } | |
89 | |
90 return errmsg; | |
91 } | |
92 | |
93 #else | |
94 | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
95 #include <cerrno> |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
96 |
258 | 97 std::string Socket::syserror(int errn) |
170 | 98 { |
258 | 99 return strerror(errn); |
170 | 100 } |
101 | |
102 #endif | |
103 | |
258 | 104 std::string Socket::syserror() |
170 | 105 { |
106 #if defined(_WIN32) | |
258 | 107 return syserror(WSAGetLastError()); |
108 #else | |
109 return syserror(errno); | |
170 | 110 #endif |
111 } | |
112 | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
113 /* -------------------------------------------------------- |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
114 * Standard clear implementation |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
115 * -------------------------------------------------------- */ |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
116 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
117 class Standard final : public SocketInterface { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
118 public: |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
119 void bind(Socket &s, const SocketAddress &address) override; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
120 void close(Socket &s) override; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
121 void connect(Socket &s, const SocketAddress &address) override; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
122 Socket accept(Socket &s, SocketAddress &info) override; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
123 void listen(Socket &s, int max) override; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
124 unsigned recv(Socket &s, void *data, unsigned len) override; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
125 unsigned recvfrom(Socket &s, void *data, unsigned len, SocketAddress &info) override ; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
126 unsigned send(Socket &s, const void *data, unsigned len) override; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
127 unsigned sendto(Socket &s, const void *data, unsigned len, const SocketAddress &info) override; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
128 }; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
129 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
130 void Standard::bind(Socket &s, const SocketAddress &addr) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
131 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
132 auto &sa = addr.address(); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
133 auto addrlen = addr.length(); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
134 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
135 if (::bind(s.handle(), (sockaddr *)&sa, addrlen) == SOCKET_ERROR) |
258 | 136 throw error::Failure(Socket::syserror()); |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
137 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
138 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
139 void Standard::connect(Socket &s, const SocketAddress &addr) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
140 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
141 auto &sa = addr.address(); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
142 auto addrlen = addr.length(); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
143 |
258 | 144 if (::connect(s.handle(), (sockaddr *)&sa, addrlen) == SOCKET_ERROR) { |
145 /* | |
146 * Determine if the error comes from a non-blocking connect that cannot be | |
147 * accomplished yet. | |
148 */ | |
149 #if defined(_WIN32) | |
150 if (WSAGetLastError() == WSAEWOULDBLOCK) | |
151 throw error::InProgress(); | |
152 | |
153 throw error::Failure(Socket::syserror()); | |
154 #else | |
155 if (errno == EINPROGRESS) | |
156 throw error::InProgress(); | |
157 | |
158 throw error::Failure(Socket::syserror()); | |
159 #endif | |
160 } | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
161 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
162 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
163 Socket Standard::accept(Socket &s, SocketAddress &info) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
164 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
165 Socket::Handle handle; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
166 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
167 // Store the information |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
168 sockaddr_storage address; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
169 socklen_t addrlen; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
170 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
171 addrlen = sizeof (sockaddr_storage); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
172 handle = ::accept(s.handle(), (sockaddr *)&address, &addrlen); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
173 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
174 if (handle == INVALID_SOCKET) |
258 | 175 throw error::Failure(Socket::syserror()); |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
176 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
177 // Usually accept works only with SOCK_STREAM |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
178 info = SocketAddress(address, addrlen); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
179 |
247 | 180 return Socket(handle); |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
181 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
182 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
183 void Standard::listen(Socket &s, int max) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
184 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
185 if (::listen(s.handle(), max) == SOCKET_ERROR) |
258 | 186 throw error::Failure(Socket::syserror()); |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
187 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
188 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
189 unsigned Standard::recv(Socket &s, void *data, unsigned dataLen) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
190 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
191 int nbread; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
192 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
193 nbread = ::recv(s.handle(), (Socket::Arg)data, dataLen, 0); |
258 | 194 if (nbread == SOCKET_ERROR) { |
195 #if defined(_WIN32) | |
196 if (WSAGetLastError() == WSAEWOULDBLOCK) | |
197 throw error::WouldBlock(); | |
198 | |
199 throw error::Failure(Socket::syserror()); | |
200 #else | |
201 if (errno == EAGAIN || errno == EWOULDBLOCK) | |
202 throw error::WouldBlock(); | |
203 | |
204 throw error::Failure(Socket::syserror()); | |
205 #endif | |
206 } | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
207 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
208 return (unsigned)nbread; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
209 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
210 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
211 unsigned Standard::send(Socket &s, const void *data, unsigned dataLen) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
212 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
213 int nbsent; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
214 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
215 nbsent = ::send(s.handle(), (Socket::ConstArg)data, dataLen, 0); |
258 | 216 if (nbsent == SOCKET_ERROR) { |
217 #if defined(_WIN32) | |
218 if (WSAGetLastError() == WSAEWOULDBLOCK) | |
219 throw error::WouldBlock(); | |
220 | |
221 throw error::Failure(Socket::syserror()); | |
222 #else | |
223 if (errno == EAGAIN || errno == EWOULDBLOCK) | |
224 throw error::WouldBlock(); | |
225 | |
226 throw error::Failure(Socket::syserror()); | |
227 #endif | |
228 } | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
229 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
230 return (unsigned)nbsent; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
231 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
232 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
233 unsigned Standard::recvfrom(Socket &s, void *data, unsigned dataLen, SocketAddress &info) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
234 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
235 int nbread; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
236 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
237 // Store information |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
238 sockaddr_storage address; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
239 socklen_t addrlen; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
240 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
241 addrlen = sizeof (struct sockaddr_storage); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
242 nbread = ::recvfrom(s.handle(), (Socket::Arg)data, dataLen, 0, (sockaddr *)&address, &addrlen); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
243 |
259
0b3fcc5ed8eb
Socket: forget to add address in recvfrom
David Demelier <markand@malikania.fr>
parents:
258
diff
changeset
|
244 info = SocketAddress(address, addrlen); |
0b3fcc5ed8eb
Socket: forget to add address in recvfrom
David Demelier <markand@malikania.fr>
parents:
258
diff
changeset
|
245 |
258 | 246 if (nbread == SOCKET_ERROR) { |
247 #if defined(_WIN32) | |
248 if (WSAGetLastError() == WSAEWOULDBLOCK) | |
249 throw error::WouldBlock(); | |
250 | |
251 throw error::Failure(Socket::syserror()); | |
252 #else | |
253 if (errno == EAGAIN || errno == EWOULDBLOCK) | |
254 throw error::WouldBlock(); | |
255 | |
256 throw error::Failure(Socket::syserror()); | |
257 #endif | |
258 } | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
259 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
260 return (unsigned)nbread; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
261 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
262 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
263 unsigned Standard::sendto(Socket &s, const void *data, unsigned dataLen, const SocketAddress &info) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
264 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
265 int nbsent; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
266 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
267 nbsent = ::sendto(s.handle(), (Socket::ConstArg)data, dataLen, 0, (const sockaddr *)&info.address(), info.length()); |
258 | 268 if (nbsent == SOCKET_ERROR) { |
269 #if defined(_WIN32) | |
270 if (WSAGetLastError() == WSAEWOULDBLOCK) | |
271 throw error::WouldBlock(); | |
272 | |
273 throw error::Failure(Socket::syserror()); | |
274 #else | |
275 if (errno == EAGAIN || errno == EWOULDBLOCK) | |
276 throw error::WouldBlock(); | |
277 | |
278 throw error::Failure(Socket::syserror()); | |
279 #endif | |
280 } | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
281 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
282 return (unsigned)nbsent; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
283 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
284 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
285 void Standard::close(Socket &s) |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
286 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
287 (void)closesocket(s.handle()); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
288 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
289 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
290 /* -------------------------------------------------------- |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
291 * Socket code |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
292 * -------------------------------------------------------- */ |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
293 |
170 | 294 Socket::Socket(int domain, int type, int protocol) |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
295 : m_interface(std::make_unique<Standard>()) |
170 | 296 { |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
297 m_handle = socket(domain, type, protocol); |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
298 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
299 if (m_handle == INVALID_SOCKET) |
258 | 300 throw error::Failure(syserror()); |
170 | 301 } |
302 | |
247 | 303 Socket::Socket(Handle handle) |
304 : m_interface(std::make_shared<Standard>()) | |
305 , m_handle(handle) | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
306 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
307 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
308 |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
309 Socket::Handle Socket::handle() const |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
310 { |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
311 return m_handle; |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
312 } |
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
313 |
170 | 314 void Socket::blockMode(bool block) |
315 { | |
316 #if defined(O_NONBLOCK) && !defined(_WIN32) | |
317 int flags; | |
318 | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
319 if ((flags = fcntl(m_handle, F_GETFL, 0)) == -1) |
170 | 320 flags = 0; |
321 | |
258 | 322 if (block) |
170 | 323 flags &= ~(O_NONBLOCK); |
324 else | |
325 flags |= O_NONBLOCK; | |
326 | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
327 if (fcntl(m_handle, F_SETFL, flags) == -1) |
258 | 328 throw error::Failure(Socket::syserror()); |
170 | 329 #else |
330 unsigned long flags = (block) ? 0 : 1; | |
331 | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
332 if (ioctlsocket(m_handle, FIONBIO, &flags) == SOCKET_ERROR) |
258 | 333 throw error::Failure(Socket::syserror()); |
170 | 334 #endif |
335 } | |
336 | |
337 Socket Socket::accept() | |
338 { | |
339 SocketAddress dummy; | |
340 | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
341 return m_interface->accept(*this, dummy); |
170 | 342 } |
343 | |
344 unsigned Socket::send(const std::string &message) | |
345 { | |
346 return Socket::send(message.c_str(), message.length()); | |
347 } | |
348 | |
349 unsigned Socket::recvfrom(void *data, unsigned dataLen) | |
350 { | |
351 SocketAddress dummy; | |
352 | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
353 return m_interface->recvfrom(*this, data, dataLen, dummy); |
170 | 354 } |
355 | |
356 unsigned Socket::sendto(const std::string &message, const SocketAddress &info) | |
357 { | |
358 return sendto(message.c_str(), message.length(), info); | |
359 } | |
360 | |
361 bool operator==(const Socket &s1, const Socket &s2) | |
362 { | |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
363 return s1.handle() == s2.handle(); |
170 | 364 } |
174
9f22bd478f21
Add operator less because widely used
David Demelier <markand@malikania.fr>
parents:
170
diff
changeset
|
365 |
175 | 366 bool operator<(const Socket &s1, const Socket &s2) |
174
9f22bd478f21
Add operator less because widely used
David Demelier <markand@malikania.fr>
parents:
170
diff
changeset
|
367 { |
245
3c12f0e8bbb9
Converter: add cstring missing
David Demelier <markand@malikania.fr>
parents:
236
diff
changeset
|
368 return s1.handle() < s2.handle(); |
174
9f22bd478f21
Add operator less because widely used
David Demelier <markand@malikania.fr>
parents:
170
diff
changeset
|
369 } |