UDP server: ping-pong version v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sat, 20 Aug 2022 22:13:40 +0200
branchv_0
changeset 30 9fcd3ff6bd6e
parent 29 97fe991ad2cb
child 31 17cea3a6d33f
UDP server: ping-pong version
src/Socket.cpp
--- a/src/Socket.cpp	Sat Aug 20 22:12:25 2022 +0200
+++ b/src/Socket.cpp	Sat Aug 20 22:13:40 2022 +0200
@@ -189,6 +189,44 @@
 	}
 };
 
+class UDPServerSocket : public Socket {
+private:
+	AddressInfos::AddressInfo localAddress;
+	sockaddr_in6 remoteAddress = {};
+	useconds_t delay = 0;
+	FD socket;
+
+public:
+
+	UDPServerSocket(AddressInfos::AddressInfo remoteAddress) : localAddress(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<UDPServerSocket>(options, SOCK_DGRAM, IPPROTO_UDP);
+		auto ai = socket->localAddress.ai;
+		int reuseAddr = true;
+		check(::setsockopt(socket->socket.getFD(), SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof (reuseAddr)), "setsockopt SO_REUSEADDR");
+		check(::bind(socket->socket.getFD(), ai->ai_addr, ai->ai_addrlen), "bind");
+		return socket;
+	}
+
+	void send(const OutgoingMessage& message) override {
+		// receive a message first to get a remote address:
+		char buffer[8192];
+		memset((char *) &remoteAddress, 0, sizeof (remoteAddress));
+		socklen_t remoteAddressSize = sizeof (remoteAddress);
+		ssize_t msgSize = recvfrom(socket.getFD(), buffer, sizeof (buffer), 0, (sockaddr*) & remoteAddress, &remoteAddressSize);
+
+		// respond with our messsage:
+		sendto(socket.getFD(), message.data.c_str(), message.data.size(), 0, (sockaddr*) & remoteAddress, remoteAddressSize);
+	}
+
+	const IncomingMessage receive() override {
+		// TODO: UDP receive()
+		return IncomingMessage("TODO: receive() a message");
+	}
+};
+
 class TCPClientSocket : public Socket {
 private:
 	AddressInfos::AddressInfo remoteAddress;
@@ -332,7 +370,7 @@
 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPServerSocket >> (),
 	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_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPServerSocket >> (),
 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPClientSocket >> (),
 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDSClientSocket >> (),