# HG changeset patch # User František Kučera # Date 1661026420 -7200 # Node ID 9fcd3ff6bd6e8f26b60b725fa5c37d198f60cb37 # Parent 97fe991ad2cb28345932c7788bf5d784460ac329 UDP server: ping-pong version diff -r 97fe991ad2cb -r 9fcd3ff6bd6e 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 open(const SocketOptions& options) { + auto socket = openClientSocket(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> (), std::make_shared> (), std::make_shared> (), - std::make_shared> (), // TODO: correct class + std::make_shared> (), std::make_shared> (), std::make_shared> (), // TODO: correct class std::make_shared> (),