38 static const char PROTOCOL_TCP_LISTEN[] = "tcp-listen://"; |
39 static const char PROTOCOL_TCP_LISTEN[] = "tcp-listen://"; |
39 static const char PROTOCOL_UDP_LISTEN[] = "udp-listen://"; |
40 static const char PROTOCOL_UDP_LISTEN[] = "udp-listen://"; |
40 static const char PROTOCOL_UDS_LISTEN[] = "uds-listen://"; |
41 static const char PROTOCOL_UDS_LISTEN[] = "uds-listen://"; |
41 static const char PROTOCOL_SCTP_LISTEN[] = "sctp-listen://"; |
42 static const char PROTOCOL_SCTP_LISTEN[] = "sctp-listen://"; |
42 |
43 |
43 class TCPSocket : public Socket { |
44 class FD { |
|
45 private: |
|
46 int fd; |
44 public: |
47 public: |
45 |
48 |
|
49 FD(int fd) : fd(fd) { |
|
50 }; |
|
51 |
|
52 virtual ~FD() { |
|
53 close(fd); |
|
54 } |
|
55 |
|
56 int getFD() { |
|
57 return fd; |
|
58 } |
|
59 }; |
|
60 |
|
61 /** |
|
62 * @param connectionString |
|
63 * @return protocol, hostname or path, port (optional) |
|
64 */ |
|
65 static std::tuple<std::string, std::string, uint16_t> parseConnectionString(const std::string& connectionString) { |
|
66 // TODO: support „:“ in domain socket paths? |
|
67 std::regex pattern("([^:]+)://([^:]+)(:([0-9]+))?"); |
|
68 |
|
69 } |
|
70 |
|
71 class UDPSocket : public Socket { |
|
72 private: |
|
73 struct sockaddr_in remoteAddress; |
|
74 public: |
|
75 |
|
76 static std::shared_ptr<Socket> open(const std::string& connectionString) { |
|
77 std::shared_ptr<UDPSocket> s = std::make_shared<UDPSocket>(); |
|
78 memset((char *) &s->remoteAddress, 0, sizeof (s->remoteAddress)); |
|
79 s->remoteAddress.sin_family = AF_INET; |
|
80 s->remoteAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); // TODO: use getaddrinfo() instead (because of error -1 = 255.255.255.255) |
|
81 s->remoteAddress.sin_port = htons(1234); |
|
82 return s; |
|
83 } |
|
84 |
46 void send(const std::string& message) override { |
85 void send(const std::string& message) override { |
47 // TODO: TCP send() |
86 FD s(::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)); |
48 struct sockaddr_in a; |
87 sendto(s.getFD(), message.c_str(), message.size(), 0, (sockaddr*) & remoteAddress, sizeof (remoteAddress)); |
49 memset((char *) &a, 0, sizeof (a)); |
|
50 a.sin_family = AF_INET; |
|
51 a.sin_addr.s_addr = inet_addr("127.0.0.1"); // TODO: use getaddrinfo() instead (because of error -1 = 255.255.255.255) |
|
52 a.sin_port = htons(1234); |
|
53 |
|
54 int s = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
|
55 sendto(s, message.c_str(), message.size(), 0, (sockaddr*) & a, sizeof (a)); |
|
56 |
|
57 close(s); |
|
58 } |
88 } |
59 |
89 |
60 const std::string receive() override { |
90 const std::string receive() override { |
61 // TODO: TCP receive() |
91 // TODO: TCP receive() |
62 return "TODO: receive() a message"; |
92 return "TODO: receive() a message"; |
70 |
100 |
71 bool canHandle(const std::string& connectionString) override { |
101 bool canHandle(const std::string& connectionString) override { |
72 return connectionString.rfind(protocol, 0) == 0; |
102 return connectionString.rfind(protocol, 0) == 0; |
73 } |
103 } |
74 |
104 |
75 Socket* open(const std::string& connectionString) override { |
105 std::shared_ptr<Socket> open(const std::string& connectionString) override { |
76 // TODO: pass string to constructor |
106 // TODO: pass string to constructor |
77 // TODO: return shared_ptr? |
107 // TODO: return shared_ptr? |
78 return new SocketClass(); |
108 return SocketClass::open(connectionString); |
79 } |
109 } |
80 }; |
110 }; |
81 |
111 |
82 static std::vector<std::shared_ptr<SocketFactory>> factories{ |
112 static std::vector<std::shared_ptr<SocketFactory>> factories |
|
113 { |
83 // FIXME: different classes than TCPSocket |
114 // FIXME: different classes than TCPSocket |
84 std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, TCPSocket>>(), |
115 std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, UDPSocket >> (), |
85 std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, TCPSocket>>(), |
116 std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, UDPSocket >> (), |
86 std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, TCPSocket>>(), |
117 std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, UDPSocket >> (), |
87 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, TCPSocket>>(), |
118 std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, UDPSocket >> (), |
88 }; |
119 }; |
89 |
120 |
90 std::shared_ptr<SocketFactory> SocketFactory::find(const std::string& connectionString) { |
121 std::shared_ptr<SocketFactory> SocketFactory::find(const std::string& connectionString) { |
91 for (auto f : factories) if (f->canHandle(connectionString)) return f; |
122 for (auto f : factories) if (f->canHandle(connectionString)) return f; |
92 return std::shared_ptr<SocketFactory>(); |
123 throw std::logic_error("Unable to find a SocketFactory for connection string: " + connectionString); |
93 } |
124 } |
94 |
125 |
95 |
126 |
96 } |
127 } |
97 } |
128 } |