src/Socket.cpp
branchv_0
changeset 23 4d97d58d40df
parent 22 9a7c42cca24b
child 24 b668bd88ffa2
equal deleted inserted replaced
22:9a7c42cca24b 23:4d97d58d40df
   189 		// TODO: TCP receive()
   189 		// TODO: TCP receive()
   190 		return "TODO: receive() a message";
   190 		return "TODO: receive() a message";
   191 	}
   191 	}
   192 };
   192 };
   193 
   193 
   194 class SCTPStreamClientSocket : public Socket {
   194 class SCTPClientSocket : public Socket {
   195 private:
       
   196 	AddressInfos::AddressInfo remoteAddress;
       
   197 
       
   198 public:
       
   199 
       
   200 	SCTPStreamClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress) {
       
   201 	}
       
   202 
       
   203 	static std::shared_ptr<Socket> open(const SocketOptions& options) {
       
   204 		auto socket = openClientSocket<SCTPStreamClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP);
       
   205 		return socket;
       
   206 	}
       
   207 
       
   208 	void send(const std::string& message) override {
       
   209 		auto ai = remoteAddress.ai;
       
   210 		FD s(::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol));
       
   211 		check(::connect(s.getFD(), ai->ai_addr, ai->ai_addrlen), "connect socket");
       
   212 		ssize_t written = ::write(s.getFD(), message.c_str(), message.size());
       
   213 		if (written != message.size()) throw std::logic_error("writing to the socket failed");
       
   214 		// TODO: partial writes, repeat
       
   215 	}
       
   216 
       
   217 	const std::string receive() override {
       
   218 		// TODO: SCTP receive()
       
   219 		return "TODO: receive() a message";
       
   220 	}
       
   221 };
       
   222 
       
   223 class SCTPMessageClientSocket : public Socket {
       
   224 private:
   195 private:
   225 	AddressInfos::AddressInfo remoteAddress;
   196 	AddressInfos::AddressInfo remoteAddress;
   226 	FD socket;
   197 	FD socket;
   227 
   198 
   228 public:
   199 public:
   229 
   200 
   230 	SCTPMessageClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), socket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) {
   201 	SCTPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), socket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) {
   231 	}
   202 	}
   232 
   203 
   233 	static std::shared_ptr<Socket> open(const SocketOptions& options) {
   204 	static std::shared_ptr<Socket> open(const SocketOptions& options) {
   234 		auto socket = openClientSocket<SCTPMessageClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP);
   205 		auto socket = openClientSocket<SCTPClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP);
   235 		check(::connect(socket->socket.getFD(), socket->remoteAddress.ai->ai_addr, socket->remoteAddress.ai->ai_addrlen), "connect socket");
   206 		check(::connect(socket->socket.getFD(), socket->remoteAddress.ai->ai_addr, socket->remoteAddress.ai->ai_addrlen), "connect socket");
   236 		return socket;
   207 		return socket;
   237 	}
   208 	}
   238 
   209 
   239 	void send(const std::string& message) override {
   210 	void send(const std::string& message) override {
   240 		iovec iov[1];
   211 		iovec iov[1];
   241 		msghdr msg = {};
   212 		msghdr msg = {};
   242 		msg.msg_iov = iov;
   213 		msg.msg_iov = iov;
   243 		msg.msg_iov[0].iov_base = (void*) message.c_str(); // TODO: const?
   214 		msg.msg_iov[0].iov_base = (void*) message.c_str();
   244 		msg.msg_iov[0].iov_len = message.size();
   215 		msg.msg_iov[0].iov_len = message.size();
   245 		msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]);
   216 		msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]);
   246 		ssize_t written = ::sendmsg(socket.getFD(), &msg, 0);
   217 		ssize_t written = ::sendmsg(socket.getFD(), &msg, 0);
   247 		if (written != message.size()) throw std::logic_error("writing to the socket failed");
   218 		if (written != message.size()) throw std::logic_error("writing to the socket failed");
   248 		// TODO: partial writes, repeat
       
   249 	}
   219 	}
   250 
   220 
   251 	const std::string receive() override {
   221 	const std::string receive() override {
   252 		// TODO: SCTP receive()
   222 		// TODO: SCTP receive()
   253 		return "TODO: receive() a message";
   223 		return "TODO: receive() a message";
   273 {
   243 {
   274 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
   244 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
   275 			std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class
   245 			std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class
   276 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (),
   246 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (),
   277 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   247 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   278 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPStreamClientSocket >> (), // TODO: do we need a stream-mode SCTP?
   248 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPClientSocket >> (),
   279 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPMessageClientSocket >> (),
   249 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPClientSocket >> (),
   280 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP?
   250 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP?
   281 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   251 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   282 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
   252 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
   283 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   253 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   284 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
   254 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class