@@ -73,10 +73,66 @@ void SetNonBlock(SOCKET fd, bool value) {
7373#endif
7474}
7575
76+ ssize_t Poll (struct pollfd * fds, int nfds, int timeout) noexcept {
77+ #if defined(_win_)
78+ return WSAPoll (fds, nfds, timeout);
79+ #else
80+ return poll (fds, nfds, timeout);
81+ #endif
82+ }
83+
84+ SOCKET SocketConnect (const NetworkAddress& addr) {
85+ int last_err = 0 ;
86+ for (auto res = addr.Info (); res != nullptr ; res = res->ai_next ) {
87+ SOCKET s (socket (res->ai_family , res->ai_socktype , res->ai_protocol ));
88+
89+ if (s == -1 ) {
90+ continue ;
91+ }
92+
93+ SetNonBlock (s, true );
94+
95+ if (connect (s, res->ai_addr , (int )res->ai_addrlen ) != 0 ) {
96+ int err = errno;
97+ if (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK) {
98+ pollfd fd;
99+ fd.fd = s;
100+ fd.events = POLLOUT;
101+ fd.revents = 0 ;
102+ ssize_t rval = Poll (&fd, 1 , 5000 );
103+
104+ if (rval == -1 ) {
105+ throw std::system_error (errno, std::system_category (), " fail to connect" );
106+ }
107+ if (rval > 0 ) {
108+ socklen_t len = sizeof (err);
109+ getsockopt (s, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
110+
111+ if (!err) {
112+ SetNonBlock (s, false );
113+ return s;
114+ }
115+ last_err = err;
116+ }
117+ }
118+ } else {
119+ SetNonBlock (s, false );
120+ return s;
121+ }
122+ }
123+ if (last_err > 0 ) {
124+ throw std::system_error (last_err, std::system_category (), " fail to connect" );
125+ }
126+ throw std::system_error (
127+ errno, std::system_category (), " fail to connect"
128+ );
129+ }
130+
76131} // namespace
77132
78133NetworkAddress::NetworkAddress (const std::string& host, const std::string& port)
79- : info_(nullptr )
134+ : host_(host)
135+ , info_(nullptr )
80136{
81137 struct addrinfo hints;
82138 memset (&hints, 0 , sizeof (hints));
@@ -112,29 +168,37 @@ NetworkAddress::~NetworkAddress() {
112168const struct addrinfo * NetworkAddress::Info () const {
113169 return info_;
114170}
115-
116-
117- SocketHolder::SocketHolder ()
118- : handle_(-1 )
119- {
171+ const std::string & NetworkAddress::Host () const {
172+ return host_;
120173}
121174
122- SocketHolder::SocketHolder (SOCKET s)
123- : handle_(s)
124- {
125- }
126175
127- SocketHolder::SocketHolder (SocketHolder&& other) noexcept
176+ Socket::Socket (const NetworkAddress& addr)
177+ : handle_(SocketConnect(addr))
178+ {}
179+
180+ Socket::Socket (Socket&& other) noexcept
128181 : handle_(other.handle_)
129182{
130183 other.handle_ = -1 ;
131184}
132185
133- SocketHolder::~SocketHolder () {
186+ Socket& Socket::operator =(Socket&& other) noexcept {
187+ if (this != &other) {
188+ Close ();
189+
190+ handle_ = other.handle_ ;
191+ other.handle_ = -1 ;
192+ }
193+
194+ return *this ;
195+ }
196+
197+ Socket::~Socket () {
134198 Close ();
135199}
136200
137- void SocketHolder ::Close () noexcept {
201+ void Socket ::Close () {
138202 if (handle_ != -1 ) {
139203#if defined(_win_)
140204 closesocket (handle_);
@@ -145,11 +209,7 @@ void SocketHolder::Close() noexcept {
145209 }
146210}
147211
148- bool SocketHolder::Closed () const noexcept {
149- return handle_ == -1 ;
150- }
151-
152- void SocketHolder::SetTcpKeepAlive (int idle, int intvl, int cnt) noexcept {
212+ void Socket::SetTcpKeepAlive (int idle, int intvl, int cnt) noexcept {
153213 int val = 1 ;
154214
155215#if defined(_unix_)
@@ -169,7 +229,7 @@ void SocketHolder::SetTcpKeepAlive(int idle, int intvl, int cnt) noexcept {
169229#endif
170230}
171231
172- void SocketHolder ::SetTcpNoDelay (bool nodelay) noexcept {
232+ void Socket ::SetTcpNoDelay (bool nodelay) noexcept {
173233 int val = nodelay;
174234#if defined(_unix_)
175235 setsockopt (handle_, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val));
@@ -178,22 +238,14 @@ void SocketHolder::SetTcpNoDelay(bool nodelay) noexcept {
178238#endif
179239}
180240
181- SocketHolder& SocketHolder::operator = (SocketHolder&& other) noexcept {
182- if (this != &other) {
183- Close ();
184-
185- handle_ = other.handle_ ;
186- other.handle_ = -1 ;
187- }
188-
189- return *this ;
241+ std::unique_ptr<InputStream> Socket::makeInputStream () const {
242+ return std::make_unique<SocketInput>(handle_);
190243}
191244
192- SocketHolder:: operator SOCKET () const noexcept {
193- return handle_;
245+ std::unique_ptr<OutputStream> Socket::makeOutputStream () const {
246+ return std::make_unique<SocketOutput>( handle_) ;
194247}
195248
196-
197249SocketInput::SocketInput (SOCKET s)
198250 : s_(s)
199251{
@@ -262,61 +314,4 @@ NetrworkInitializer::NetrworkInitializer() {
262314 (void )Singleton<NetrworkInitializerImpl>();
263315}
264316
265-
266- SOCKET SocketConnect (const NetworkAddress& addr) {
267- int last_err = 0 ;
268- for (auto res = addr.Info (); res != nullptr ; res = res->ai_next ) {
269- SOCKET s (socket (res->ai_family , res->ai_socktype , res->ai_protocol ));
270-
271- if (s == -1 ) {
272- continue ;
273- }
274-
275- SetNonBlock (s, true );
276-
277- if (connect (s, res->ai_addr , (int )res->ai_addrlen ) != 0 ) {
278- int err = errno;
279- if (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK) {
280- pollfd fd;
281- fd.fd = s;
282- fd.events = POLLOUT;
283- fd.revents = 0 ;
284- ssize_t rval = Poll (&fd, 1 , 5000 );
285-
286- if (rval == -1 ) {
287- throw std::system_error (errno, std::system_category (), " fail to connect" );
288- }
289- if (rval > 0 ) {
290- socklen_t len = sizeof (err);
291- getsockopt (s, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
292-
293- if (!err) {
294- SetNonBlock (s, false );
295- return s;
296- }
297- last_err = err;
298- }
299- }
300- } else {
301- SetNonBlock (s, false );
302- return s;
303- }
304- }
305- if (last_err > 0 ) {
306- throw std::system_error (last_err, std::system_category (), " fail to connect" );
307- }
308- throw std::system_error (
309- errno, std::system_category (), " fail to connect"
310- );
311- }
312-
313-
314- ssize_t Poll (struct pollfd * fds, int nfds, int timeout) noexcept {
315- #if defined(_win_)
316- return WSAPoll (fds, nfds, timeout);
317- #else
318- return poll (fds, nfds, timeout);
319- #endif
320- }
321-
322317}
0 commit comments