189 // TODO: TCP receive() |
189 // TODO: TCP receive() |
190 return "TODO: receive() a message"; |
190 return "TODO: receive() a message"; |
191 } |
191 } |
192 }; |
192 }; |
193 |
193 |
194 class SCTPStreamClientSocket : public Socket { |
194 class SCTPClientSocket : public Socket { |
195 private: |
|
196 AddressInfos::AddressInfo remoteAddress; |
|
197 |
|
198 public: |
|
199 |
|
200 SCTPStreamClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress) { |
|
201 } |
|
202 |
|
203 static std::shared_ptr<Socket> open(const SocketOptions& options) { |
|
204 auto socket = openClientSocket<SCTPStreamClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP); |
|
205 return socket; |
|
206 } |
|
207 |
|
208 void send(const std::string& message) override { |
|
209 auto ai = remoteAddress.ai; |
|
210 FD s(::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)); |
|
211 check(::connect(s.getFD(), ai->ai_addr, ai->ai_addrlen), "connect socket"); |
|
212 ssize_t written = ::write(s.getFD(), message.c_str(), message.size()); |
|
213 if (written != message.size()) throw std::logic_error("writing to the socket failed"); |
|
214 // TODO: partial writes, repeat |
|
215 } |
|
216 |
|
217 const std::string receive() override { |
|
218 // TODO: SCTP receive() |
|
219 return "TODO: receive() a message"; |
|
220 } |
|
221 }; |
|
222 |
|
223 class SCTPMessageClientSocket : public Socket { |
|
224 private: |
195 private: |
225 AddressInfos::AddressInfo remoteAddress; |
196 AddressInfos::AddressInfo remoteAddress; |
226 FD socket; |
197 FD socket; |
227 |
198 |
228 public: |
199 public: |
229 |
200 |
230 SCTPMessageClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), socket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) { |
201 SCTPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), socket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) { |
231 } |
202 } |
232 |
203 |
233 static std::shared_ptr<Socket> open(const SocketOptions& options) { |
204 static std::shared_ptr<Socket> open(const SocketOptions& options) { |
234 auto socket = openClientSocket<SCTPMessageClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP); |
205 auto socket = openClientSocket<SCTPClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP); |
235 check(::connect(socket->socket.getFD(), socket->remoteAddress.ai->ai_addr, socket->remoteAddress.ai->ai_addrlen), "connect socket"); |
206 check(::connect(socket->socket.getFD(), socket->remoteAddress.ai->ai_addr, socket->remoteAddress.ai->ai_addrlen), "connect socket"); |
236 return socket; |
207 return socket; |
237 } |
208 } |
238 |
209 |
239 void send(const std::string& message) override { |
210 void send(const std::string& message) override { |
240 iovec iov[1]; |
211 iovec iov[1]; |
241 msghdr msg = {}; |
212 msghdr msg = {}; |
242 msg.msg_iov = iov; |
213 msg.msg_iov = iov; |
243 msg.msg_iov[0].iov_base = (void*) message.c_str(); // TODO: const? |
214 msg.msg_iov[0].iov_base = (void*) message.c_str(); |
244 msg.msg_iov[0].iov_len = message.size(); |
215 msg.msg_iov[0].iov_len = message.size(); |
245 msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]); |
216 msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]); |
246 ssize_t written = ::sendmsg(socket.getFD(), &msg, 0); |
217 ssize_t written = ::sendmsg(socket.getFD(), &msg, 0); |
247 if (written != message.size()) throw std::logic_error("writing to the socket failed"); |
218 if (written != message.size()) throw std::logic_error("writing to the socket failed"); |
248 // TODO: partial writes, repeat |
|
249 } |
219 } |
250 |
220 |
251 const std::string receive() override { |
221 const std::string receive() override { |
252 // TODO: SCTP receive() |
222 // TODO: SCTP receive() |
253 return "TODO: receive() a message"; |
223 return "TODO: receive() a message"; |
273 { |
243 { |
274 std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (), |
244 std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (), |
275 std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class |
245 std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class |
276 std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), |
246 std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), |
277 std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class |
247 std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class |
278 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPStreamClientSocket >> (), // TODO: do we need a stream-mode SCTP? |
248 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPClientSocket >> (), |
279 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPMessageClientSocket >> (), |
249 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPClientSocket >> (), |
280 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP? |
250 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP? |
281 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class |
251 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class |
282 std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class |
252 std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class |
283 std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class |
253 std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class |
284 std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class |
254 std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class |