src/Socket.cpp
branchv_0
changeset 27 e6e5780339bd
parent 26 07949ba141b7
child 28 f2697551bfd5
equal deleted inserted replaced
26:07949ba141b7 27:e6e5780339bd
   152 public:
   152 public:
   153 
   153 
   154 	MSGSocket(int socket) : socket(socket) {
   154 	MSGSocket(int socket) : socket(socket) {
   155 	}
   155 	}
   156 
   156 
   157 	void send(const std::string& message) {
   157 	void send(const OutgoingMessage& message) {
   158 		sendmsg(message);
   158 		sendmsg(message.data);
   159 	}
   159 	}
   160 
   160 
   161 };
   161 };
   162 
   162 
   163 class UDPClientSocket : public Socket {
   163 class UDPClientSocket : public Socket {
   175 		auto socket = openClientSocket<UDPClientSocket>(options, SOCK_DGRAM, IPPROTO_UDP);
   175 		auto socket = openClientSocket<UDPClientSocket>(options, SOCK_DGRAM, IPPROTO_UDP);
   176 		socket->delay = std::stol(findOption(options, OPTION_DELAY, false, "0")); // TODO: Move to SocketHandler? Or delete.
   176 		socket->delay = std::stol(findOption(options, OPTION_DELAY, false, "0")); // TODO: Move to SocketHandler? Or delete.
   177 		return socket;
   177 		return socket;
   178 	}
   178 	}
   179 
   179 
   180 	void send(const std::string& message) override {
   180 	void send(const OutgoingMessage& message) override {
   181 		auto ai = remoteAddress.ai;
   181 		auto ai = remoteAddress.ai;
   182 		sendto(socket.getFD(), message.c_str(), message.size(), 0, ai->ai_addr, ai->ai_addrlen);
   182 		sendto(socket.getFD(), message.data.c_str(), message.data.size(), 0, ai->ai_addr, ai->ai_addrlen);
   183 		if (delay) usleep(delay);
   183 		if (delay) usleep(delay);
   184 	}
   184 	}
   185 
   185 
   186 	const std::string receive() override {
   186 	const IncomingMessage receive() override {
   187 		// TODO: UDP receive()
   187 		// TODO: UDP receive()
   188 		return "TODO: receive() a message";
   188 		return IncomingMessage("TODO: receive() a message");
   189 	}
   189 	}
   190 };
   190 };
   191 
   191 
   192 class TCPClientSocket : public Socket {
   192 class TCPClientSocket : public Socket {
   193 private:
   193 private:
   200 
   200 
   201 	static std::shared_ptr<Socket> open(const SocketOptions& options) {
   201 	static std::shared_ptr<Socket> open(const SocketOptions& options) {
   202 		return openClientSocket<TCPClientSocket>(options, SOCK_STREAM, IPPROTO_TCP);
   202 		return openClientSocket<TCPClientSocket>(options, SOCK_STREAM, IPPROTO_TCP);
   203 	}
   203 	}
   204 
   204 
   205 	void send(const std::string& message) override {
   205 	void send(const OutgoingMessage& message) override {
   206 		auto ai = remoteAddress.ai;
   206 		auto ai = remoteAddress.ai;
   207 		FD s(::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol));
   207 		FD s(::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol));
   208 		check(::connect(s.getFD(), ai->ai_addr, ai->ai_addrlen), "connect socket");
   208 		check(::connect(s.getFD(), ai->ai_addr, ai->ai_addrlen), "connect socket");
   209 		ssize_t written = ::write(s.getFD(), message.c_str(), message.size());
   209 		ssize_t written = ::write(s.getFD(), message.data.c_str(), message.data.size());
   210 		if (written != message.size()) throw std::logic_error("writing to the socket failed");
   210 		if (written != message.data.size()) throw std::logic_error("writing to the socket failed");
   211 		// TODO: partial writes, repeat
   211 		// TODO: partial writes, repeat
   212 	}
   212 	}
   213 
   213 
   214 	const std::string receive() override {
   214 	const IncomingMessage receive() override {
   215 		// TODO: TCP receive()
   215 		// TODO: TCP receive()
   216 		return "TODO: receive() a message";
   216 		return IncomingMessage("TODO: receive() a message");
   217 	}
   217 	}
   218 };
   218 };
   219 
   219 
   220 class SCTPClientSocket : public MSGSocket {
   220 class SCTPClientSocket : public MSGSocket {
   221 private:
   221 private:
   229 		auto socket = openClientSocket<SCTPClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP);
   229 		auto socket = openClientSocket<SCTPClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP);
   230 		check(::connect(socket->socket.getFD(), socket->remoteAddress.ai->ai_addr, socket->remoteAddress.ai->ai_addrlen), "connect socket");
   230 		check(::connect(socket->socket.getFD(), socket->remoteAddress.ai->ai_addr, socket->remoteAddress.ai->ai_addrlen), "connect socket");
   231 		return socket;
   231 		return socket;
   232 	}
   232 	}
   233 
   233 
   234 	const std::string receive() override {
   234 	const IncomingMessage receive() override {
   235 		// TODO: SCTP receive()
   235 		// TODO: SCTP receive()
   236 		return "TODO: receive() a message";
   236 		return IncomingMessage("TODO: receive() a message");
   237 	}
   237 	}
   238 };
   238 };
   239 
   239 
   240 class UDSClientSocket : public MSGSocket {
   240 class UDSClientSocket : public MSGSocket {
   241 public:
   241 public:
   272 
   272 
   273 
   273 
   274 		return socket;
   274 		return socket;
   275 	}
   275 	}
   276 
   276 
   277 	const std::string receive() override {
   277 	const IncomingMessage receive() override {
   278 		// TODO: UDS receive()
   278 		// TODO: UDS receive()
   279 		return "TODO: receive() a message";
   279 		return IncomingMessage("TODO: receive() a message");
   280 	}
   280 	}
   281 };
   281 };
   282 
   282 
   283 template<const char* protocol, const char* role, const char* mode, typename SocketClass>
   283 template<const char* protocol, const char* role, const char* mode, typename SocketClass>
   284 class TemplateSocketFactory : public SocketFactory {
   284 class TemplateSocketFactory : public SocketFactory {
   300 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
   300 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
   301 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class
   301 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class
   302 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (),
   302 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (),
   303 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   303 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   304 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPClientSocket >> (),
   304 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPClientSocket >> (),
   305 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPClientSocket >> (),
       
   306 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP?
   305 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP?
   307 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
       
   308 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDSClientSocket >> (),
   306 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDSClientSocket >> (),
   309 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
   307 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
   310 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDSClientSocket >> (), // TODO: correct class
   308 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDSClientSocket >> (), // TODO: correct class
   311 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
   309 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
   312 };
   310 };