SCTP: sendmsg() v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Thu, 18 Aug 2022 03:39:55 +0200
branchv_0
changeset 22 9a7c42cca24b
parent 21 1c6c86697837
child 23 4d97d58d40df
SCTP: sendmsg()
src/Socket.cpp
--- a/src/Socket.cpp	Wed Aug 17 23:28:20 2022 +0200
+++ b/src/Socket.cpp	Thu Aug 18 03:39:55 2022 +0200
@@ -220,6 +220,40 @@
 	}
 };
 
+class SCTPMessageClientSocket : public Socket {
+private:
+	AddressInfos::AddressInfo remoteAddress;
+	FD socket;
+
+public:
+
+	SCTPMessageClientSocket(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) {
+		auto socket = openClientSocket<SCTPMessageClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP);
+		check(::connect(socket->socket.getFD(), socket->remoteAddress.ai->ai_addr, socket->remoteAddress.ai->ai_addrlen), "connect socket");
+		return socket;
+	}
+
+	void send(const std::string& message) override {
+		iovec iov[1];
+		msghdr msg = {};
+		msg.msg_iov = iov;
+		msg.msg_iov[0].iov_base = (void*) message.c_str(); // TODO: const?
+		msg.msg_iov[0].iov_len = message.size();
+		msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]);
+		ssize_t written = ::sendmsg(socket.getFD(), &msg, 0);
+		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>
 class TemplateSocketFactory : public SocketFactory {
 public:
@@ -242,7 +276,7 @@
 			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, 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_CLIENT, MODE_DATAGRAM, SCTPMessageClientSocket >> (),
 			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