--- a/src/Socket.cpp Sat Jul 30 12:58:14 2022 +0200
+++ b/src/Socket.cpp Sat Jul 30 23:25:23 2022 +0200
@@ -57,13 +57,53 @@
}
};
-class UDPSocket : public Socket {
+static void check(int result, std::string message) {
+ if (result == 0); // OK
+ else throw std::logic_error("Got error result: " + std::to_string(result) + " - " + message);
+}
+
+class UDPClientSocket : public Socket {
+private:
+ struct sockaddr_in remoteAddress;
+ int protocol = IPPROTO_UDP;
+ int type = SOCK_DGRAM;
+public:
+
+ static std::shared_ptr<Socket> open(const SocketOptions& options) {
+ std::shared_ptr<UDPClientSocket> s = std::make_shared<UDPClientSocket>();
+ memset((char *) &s->remoteAddress, 0, sizeof (s->remoteAddress));
+ s->remoteAddress.sin_family = AF_INET;
+ s->remoteAddress.sin_addr.s_addr = inet_addr(findOption(options, OPTION_HOST, true).c_str()); // TODO: use getaddrinfo() instead (because of error -1 = 255.255.255.255)
+ s->remoteAddress.sin_port = htons(std::stoi(findOption(options, OPTION_PORT, true)));
+
+ auto protocol = findOption(options, OPTION_PROTOCOL);
+ if (protocol == PROTOCOL_SCTP) {
+ s->protocol = IPPROTO_SCTP;
+ s->type = SOCK_SEQPACKET;
+ }
+
+ return s;
+ }
+
+ void send(const std::string& message) override {
+ FD s(::socket(AF_INET, type, protocol));
+ sendto(s.getFD(), message.c_str(), message.size(), 0, (sockaddr*) & remoteAddress, sizeof (remoteAddress));
+ }
+
+ const std::string receive() override {
+ // TODO: TCP receive()
+ return "TODO: receive() a message";
+ }
+
+};
+
+class TCPClientSocket : public Socket {
private:
struct sockaddr_in remoteAddress;
public:
static std::shared_ptr<Socket> open(const SocketOptions& options) {
- std::shared_ptr<UDPSocket> s = std::make_shared<UDPSocket>();
+ std::shared_ptr<TCPClientSocket> s = std::make_shared<TCPClientSocket>();
memset((char *) &s->remoteAddress, 0, sizeof (s->remoteAddress));
s->remoteAddress.sin_family = AF_INET;
s->remoteAddress.sin_addr.s_addr = inet_addr(findOption(options, OPTION_HOST, true).c_str()); // TODO: use getaddrinfo() instead (because of error -1 = 255.255.255.255)
@@ -72,8 +112,10 @@
}
void send(const std::string& message) override {
- FD s(::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
- sendto(s.getFD(), message.c_str(), message.size(), 0, (sockaddr*) & remoteAddress, sizeof (remoteAddress));
+ FD s(::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
+ check(::connect(s.getFD(), (sockaddr*) & remoteAddress, sizeof (remoteAddress)), "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");
}
const std::string receive() override {
@@ -81,6 +123,7 @@
return "TODO: receive() a message";
}
+
};
template<const char* protocol, const char* role, const char* mode, typename SocketClass>
@@ -100,19 +143,18 @@
static std::vector<std::shared_ptr<SocketFactory>> factories
{
- // FIXME: different classes than UDPSocket
- std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDPSocket >> (),
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDPSocket >> (),
+ std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
+ 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_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
+ std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
+ std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
};
std::shared_ptr<SocketFactory> SocketFactory::find(const SocketOptions& options) {