133 protocol); |
133 protocol); |
134 |
134 |
135 return std::shared_ptr<SocketClass>(new SocketClass(remoteAddresses[0], moreArgs...)); |
135 return std::shared_ptr<SocketClass>(new SocketClass(remoteAddresses[0], moreArgs...)); |
136 } |
136 } |
137 |
137 |
138 void sendmsg(int fd, const std::string& message) { |
138 class MSGSocket : public Socket { |
139 iovec iov[1]; |
139 protected: |
140 msghdr msg = {}; |
140 FD socket; |
141 msg.msg_iov = iov; |
141 |
142 msg.msg_iov[0].iov_base = (void*) message.c_str(); |
142 void sendmsg(const std::string& message) { |
143 msg.msg_iov[0].iov_len = message.size(); |
143 iovec iov[1]; |
144 msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]); |
144 msghdr msg = {}; |
145 ssize_t written = ::sendmsg(fd, &msg, 0); |
145 msg.msg_iov = iov; |
146 if (written != message.size()) throw std::logic_error("writing to the socket failed"); |
146 msg.msg_iov[0].iov_base = (void*) message.c_str(); |
147 } |
147 msg.msg_iov[0].iov_len = message.size(); |
|
148 msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]); |
|
149 ssize_t written = ::sendmsg(socket.getFD(), &msg, 0); |
|
150 if (written != message.size()) throw std::logic_error("writing to the socket failed"); |
|
151 } |
|
152 public: |
|
153 |
|
154 MSGSocket(int socket) : socket(socket) { |
|
155 } |
|
156 |
|
157 void send(const std::string& message) { |
|
158 sendmsg(message); |
|
159 } |
|
160 |
|
161 }; |
148 |
162 |
149 class UDPClientSocket : public Socket { |
163 class UDPClientSocket : public Socket { |
150 private: |
164 private: |
151 AddressInfos::AddressInfo remoteAddress; |
165 AddressInfos::AddressInfo remoteAddress; |
152 useconds_t delay = 0; |
166 useconds_t delay = 0; |
201 // TODO: TCP receive() |
215 // TODO: TCP receive() |
202 return "TODO: receive() a message"; |
216 return "TODO: receive() a message"; |
203 } |
217 } |
204 }; |
218 }; |
205 |
219 |
206 class SCTPClientSocket : public Socket { |
220 class SCTPClientSocket : public MSGSocket { |
207 private: |
221 private: |
208 AddressInfos::AddressInfo remoteAddress; |
222 AddressInfos::AddressInfo remoteAddress; |
209 FD socket; |
223 public: |
210 |
224 |
211 public: |
225 SCTPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), MSGSocket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) { |
212 |
|
213 SCTPClientSocket(AddressInfos::AddressInfo remoteAddress) : remoteAddress(remoteAddress), socket(::socket(remoteAddress.ai->ai_family, remoteAddress.ai->ai_socktype, remoteAddress.ai->ai_protocol)) { |
|
214 } |
226 } |
215 |
227 |
216 static std::shared_ptr<Socket> open(const SocketOptions& options) { |
228 static std::shared_ptr<Socket> open(const SocketOptions& options) { |
217 auto socket = openClientSocket<SCTPClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP); |
229 auto socket = openClientSocket<SCTPClientSocket>(options, SOCK_STREAM, IPPROTO_SCTP); |
218 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"); |
219 return socket; |
231 return socket; |
220 } |
232 } |
221 |
233 |
222 void send(const std::string& message) override { |
|
223 sendmsg(socket.getFD(), message); |
|
224 } |
|
225 |
|
226 const std::string receive() override { |
234 const std::string receive() override { |
227 // TODO: SCTP receive() |
235 // TODO: SCTP receive() |
228 return "TODO: receive() a message"; |
236 return "TODO: receive() a message"; |
229 } |
237 } |
230 }; |
238 }; |
231 |
239 |
232 class UDSClientSocket : public Socket { |
240 class UDSClientSocket : public MSGSocket { |
233 private: |
241 public: |
234 FD socket; |
242 |
235 |
243 UDSClientSocket(int fd) : MSGSocket(fd) { |
236 public: |
|
237 |
|
238 UDSClientSocket(int fd) : socket(fd) { |
|
239 } |
244 } |
240 |
245 |
241 static std::shared_ptr<Socket> open(const SocketOptions& options) { |
246 static std::shared_ptr<Socket> open(const SocketOptions& options) { |
242 struct sockaddr_un address; |
247 struct sockaddr_un address; |
243 std::string path = findOption(options, OPTION_PATH); |
248 std::string path = findOption(options, OPTION_PATH); |