src/Socket.cpp
branchv_0
changeset 4 8d036e5e5fcc
parent 3 e701e06ff561
child 5 e57e2a2798b2
equal deleted inserted replaced
3:e701e06ff561 4:8d036e5e5fcc
    22 #include <sys/types.h>
    22 #include <sys/types.h>
    23 #include <sys/socket.h>
    23 #include <sys/socket.h>
    24 #include <netinet/in.h>
    24 #include <netinet/in.h>
    25 #include <vector>
    25 #include <vector>
    26 #include <memory>
    26 #include <memory>
       
    27 #include <regex>
    27 
    28 
    28 #include "Socket.h"
    29 #include "Socket.h"
    29 
    30 
    30 namespace relpipe {
    31 namespace relpipe {
    31 namespace out {
    32 namespace out {
    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 }