--- a/src/Socket.cpp Sun Aug 07 15:31:51 2022 +0200
+++ b/src/Socket.cpp Wed Aug 17 23:28:20 2022 +0200
@@ -124,45 +124,43 @@
};
-template<class SocketClass> static std::shared_ptr<SocketClass> openClientSocket(const SocketOptions& options, int socketType, int protocol) {
+template<class SocketClass, class... MoreArgs> static std::shared_ptr<SocketClass> openClientSocket(const SocketOptions& options, int socketType, int protocol, MoreArgs... moreArgs) {
AddressInfos remoteAddresses = AddressInfos::getAddressInfos(
findOption(options, OPTION_HOST, true),
findOption(options, OPTION_PORT, true),
socketType,
protocol);
- return std::shared_ptr<SocketClass>(new SocketClass(remoteAddresses[0]));
+ return std::shared_ptr<SocketClass>(new SocketClass(remoteAddresses[0], moreArgs...));
}
class UDPClientSocket : public Socket {
private:
AddressInfos::AddressInfo remoteAddress;
useconds_t delay = 0;
+ FD socket;
public:
- UDPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress) {
+ UDPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), socket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) {
}
static std::shared_ptr<Socket> open(const SocketOptions& options) {
- bool sctp = findOption(options, OPTION_PROTOCOL) == PROTOCOL_SCTP;
- auto socket = openClientSocket<UDPClientSocket>(options, sctp ? SOCK_SEQPACKET : SOCK_DGRAM, sctp ? IPPROTO_SCTP : IPPROTO_UDP);
- socket->delay = std::stol(findOption(options, OPTION_DELAY, false, "0"));
+ auto socket = openClientSocket<UDPClientSocket>(options, SOCK_DGRAM, IPPROTO_UDP);
+ socket->delay = std::stol(findOption(options, OPTION_DELAY, false, "0")); // TODO: Move to SocketHandler? Or delete.
return socket;
}
void send(const std::string& message) override {
auto ai = remoteAddress.ai;
- FD s(::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol));
- sendto(s.getFD(), message.c_str(), message.size(), 0, ai->ai_addr, ai->ai_addrlen);
+ sendto(socket.getFD(), message.c_str(), message.size(), 0, ai->ai_addr, ai->ai_addrlen);
if (delay) usleep(delay);
}
const std::string receive() override {
- // TODO: TCP receive()
+ // TODO: UDP receive()
return "TODO: receive() a message";
}
-
};
class TCPClientSocket : public Socket {
@@ -191,8 +189,35 @@
// TODO: TCP receive()
return "TODO: receive() a message";
}
+};
+class SCTPStreamClientSocket : public Socket {
+private:
+ AddressInfos::AddressInfo remoteAddress;
+public:
+
+ SCTPStreamClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress) {
+ }
+
+ static std::shared_ptr<Socket> open(const SocketOptions& options) {
+ auto socket = openClientSocket<SCTPStreamClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP);
+ return socket;
+ }
+
+ void send(const std::string& message) override {
+ auto ai = remoteAddress.ai;
+ FD s(::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol));
+ check(::connect(s.getFD(), ai->ai_addr, ai->ai_addrlen), "connect socket");
+ ssize_t written = ::write(s.getFD(), message.c_str(), message.size());
+ if (written != message.size()) throw std::logic_error("writing to the socket failed");
+ // TODO: partial writes, repeat
+ }
+
+ const std::string receive() override {
+ // TODO: SCTP receive()
+ return "TODO: receive() a message";
+ }
};
template<const char* protocol, const char* role, const char* mode, typename SocketClass>
@@ -216,9 +241,9 @@
std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class
std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (),
std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
- std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
- std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
- std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
+ std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPStreamClientSocket >> (), // TODO: do we need a stream-mode SCTP?
+ std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPStreamClientSocket >> (),
+ std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP?
std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class