annotate C++/SocketTcp.cpp @ 316:4c0af1143fc4

Add wait operation (no tests yet)
author David Demelier <markand@malikania.fr>
date Tue, 03 Mar 2015 18:48:54 +0100
parents c9356cb38c86
children 890729b8cb60
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
315
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * SocketTcp.cpp -- portable C++ socket wrappers
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include "SocketAddress.h"
316
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
20 #include "SocketListener.h"
315
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include "SocketTcp.h"
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
22
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 /* --------------------------------------------------------
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 * SocketAbstractTcp
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 * -------------------------------------------------------- */
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 void SocketAbstractTcp::listen(int max)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 if (::listen(m_handle, max) == Error)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 throw SocketError("listen", Socket::syserror(), errno);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 }
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
32
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 /* --------------------------------------------------------
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 * SocketTcp
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 * -------------------------------------------------------- */
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
36
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 SocketTcp SocketTcp::accept()
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 SocketAddress dummy;
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
40
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 return accept(dummy);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 }
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
43
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 SocketTcp SocketTcp::accept(SocketAddress &info)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 Socket::Handle handle;
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
47
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 // Store the information
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 sockaddr_storage address;
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 socklen_t addrlen;
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
51
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 addrlen = sizeof (sockaddr_storage);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 handle = ::accept(m_handle, reinterpret_cast<sockaddr *>(&address), &addrlen);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
54
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 if (handle == Invalid) {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 #if defined(_WIN32)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 if (WSAGetLastError() == WSAEWOULDBLOCK)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 throw SocketError("accept", Socket::syserror(WSAEWOULDBLOCK), WSAEWOULDBLOCK /* TODO: Read */);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
59
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 throw SocketError("accept", Socket::syserror(), WSAGetLastError());
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 #else
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 if (errno == EAGAIN || errno == EWOULDBLOCK)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 throw SocketError("accept", Socket::syserror(EWOULDBLOCK), EWOULDBLOCK /* TODO: Read */);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
64
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 throw SocketError("accept", Socket::syserror(), errno);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 #endif
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 }
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 // Usually accept works only with SOCK_STREAM
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 info = SocketAddress(address, addrlen);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
71
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 return SocketTcp(handle);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 }
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
74
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 void SocketTcp::connect(const SocketAddress &address)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 {
316
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
77 if (m_state == SocketState::Connected)
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
78 return;
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
79
315
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 auto &sa = address.address();
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 auto addrlen = address.length();
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
82
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 if (::connect(m_handle, reinterpret_cast<const sockaddr *>(&sa), addrlen) == Error) {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 /*
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 * Determine if the error comes from a non-blocking connect that cannot be
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 * accomplished yet.
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 */
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 #if defined(_WIN32)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 if (WSAGetLastError() == WSAEWOULDBLOCK)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 throw SocketError("connect", Socket::syserror(WSAEWOULDBLOCK), WSAEWOULDBLOCK /*, Write */);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
91
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 throw SocketError("connect", Socket::syserror(WSAEWOULDBLOCK), WSAGetLastError());
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 #else
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 if (errno == EINPROGRESS)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 throw SocketError("connect", Socket::syserror(EINPROGRESS), EINPROGRESS /*, Write */);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
96
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 throw SocketError("connect", Socket::syserror(), errno);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 #endif
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 }
316
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
100
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
101 m_state = SocketState::Connected;
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
102 }
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
103
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
104 void SocketTcp::waitConnect(const SocketAddress &address, int timeout)
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
105 {
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
106 if (m_state == SocketState::Connected)
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
107 return;
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
108
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
109 // Initial try
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
110 try {
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
111 connect(address);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
112 } catch (const SocketError &ex) {
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
113 // TODO: HANDLE ERROR CODE
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
114
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
115 SocketListener listener{{*this, SocketListener::Write}};
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
116
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
117 listener.select(timeout);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
118
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
119 // Socket is writable? Check if there is an error
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
120 int error = get<int>(SOL_SOCKET, SO_ERROR);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
121
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
122 if (error) {
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
123 throw SocketError("connect", Socket::syserror(error), error);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
124 }
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
125 }
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
126
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
127 m_state = SocketState::Connected;
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
128 }
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
129
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
130 SocketTcp SocketTcp::waitAccept(int timeout)
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
131 {
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
132 SocketAddress dummy;
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
133
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
134 return waitAccept(dummy, timeout);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
135 }
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
136
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
137 SocketTcp SocketTcp::waitAccept(SocketAddress &info, int timeout)
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
138 {
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
139 SocketListener listener{{*this, SocketListener::Read}};
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
140
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
141 listener.select(timeout);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
142
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
143 return accept(info);
315
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 }
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
145
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 unsigned SocketTcp::recv(void *data, unsigned dataLen)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 int nbread;
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
149
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 nbread = ::recv(m_handle, (Socket::Arg)data, dataLen, 0);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 if (nbread == Error) {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 #if defined(_WIN32)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 if (WSAGetLastError() == WSAEWOULDBLOCK)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 throw SocketError("recv", Socket::syserror(), WSAEWOULDBLOCK /* TODO: Read */);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
155
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 throw SocketError("recv", Socket::syserror(), WSAGetLastError());
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 #else
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 if (errno == EAGAIN || errno == EWOULDBLOCK)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 throw SocketError("recv", Socket::syserror(), errno /* TODO: Read */);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
160
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 throw SocketError("recv", Socket::syserror(), errno);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 #endif
316
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
163 } else if (nbread == 0)
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
164 m_state = SocketState::Closed;
315
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
165
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 return (unsigned)nbread;
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 }
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
168
316
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
169 unsigned SocketTcp::waitRecv(void *data, unsigned length, int timeout)
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
170 {
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
171 SocketListener listener{{*this, SocketListener::Read}};
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
172
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
173 listener.select(timeout);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
174
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
175 return recv(data, length);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
176 }
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
177
315
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 unsigned SocketTcp::send(const void *data, unsigned length)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 int nbsent;
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
181
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 nbsent = ::send(m_handle, (Socket::ConstArg)data, length, 0);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 if (nbsent == Error) {
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 #if defined(_WIN32)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 if (WSAGetLastError() == WSAEWOULDBLOCK)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 throw SocketError("send", Socket::syserror(), WSAEWOULDBLOCK /* Write */);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
187
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 throw SocketError("send", Socket::syserror(), WSAGetLastError());
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 #else
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 if (errno == EAGAIN || errno == EWOULDBLOCK)
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 throw SocketError("send", Socket::syserror(), errno /*, Write */);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
192
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 throw SocketError("send", Socket::syserror(), errno);
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 #endif
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 }
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
196
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 return (unsigned)nbsent;
c9356cb38c86 Split sockets into SocketTcp and SocketUdp
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 }
316
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
199
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
200 unsigned SocketTcp::waitSend(const void *data, unsigned length, int timeout)
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
201 {
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
202 SocketListener listener{{*this, SocketListener::Write}};
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
203
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
204 listener.select(timeout);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
205
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
206 return send(data, length);
4c0af1143fc4 Add wait operation (no tests yet)
David Demelier <markand@malikania.fr>
parents: 315
diff changeset
207 }