diff options
author | pixel <pixel> | 2007-03-05 21:40:44 +0000 |
---|---|---|
committer | pixel <pixel> | 2007-03-05 21:40:44 +0000 |
commit | 03aff7d93cf57507da3483601ef692b39330ac33 (patch) | |
tree | a4103c9234ed6df3ff6201edb152907ff5bc5357 | |
parent | 657c7d68d3fde9ff7042149d51f55ca36e5c8385 (diff) |
Socket now have non-blocking connect() support.
-rw-r--r-- | include/Socket.h | 4 | ||||
-rw-r--r-- | lib/Socket.cc | 33 |
2 files changed, 32 insertions, 5 deletions
diff --git a/include/Socket.h b/include/Socket.h index 4c79237..f65c214 100644 --- a/include/Socket.h +++ b/include/Socket.h @@ -17,6 +17,7 @@ class Socket : public Handle { bool Listen(); Socket Accept() throw (GeneralException); bool IsConnected(); + bool IsConnecting(); bool IsListening(); virtual bool CanRead(); virtual bool CanWrite(); @@ -24,6 +25,7 @@ class Socket : public Handle { int GetPort(); void CloseWrite(); void CloseRead(); + bool FinalizeConnect(); protected: virtual ssize_t nwrite(const void *, size_t) throw (GeneralException); virtual ssize_t nread(void *, size_t) throw (GeneralException); @@ -32,7 +34,7 @@ class Socket : public Handle { private: Socket(int s); - bool connected, listening, writeclosed, readclosed; + bool connected, listening, writeclosed, readclosed, connecting; }; #endif diff --git a/lib/Socket.cc b/lib/Socket.cc index f417bf9..97371a5 100644 --- a/lib/Socket.cc +++ b/lib/Socket.cc @@ -35,19 +35,19 @@ class dummy_win32_socket_class_t : public Base { typedef int socklen_t; #endif -Socket::Socket() throw (GeneralException) : Handle(socket(AF_INET, SOCK_STREAM, 0)), connected(false), listening(false), writeclosed(false), readclosed(false) { +Socket::Socket() throw (GeneralException) : Handle(socket(AF_INET, SOCK_STREAM, 0)), connected(false), listening(false), writeclosed(false), readclosed(false), connecting(false) { // cerr << "Socket(): connected = " << connected << "; readclosed = " << readclosed << "; writeclosed = " << writeclosed << endl; if (GetHandle() < 0) { throw GeneralException(_("Error creating socket.")); } } -Socket::Socket(const Socket & s) : Handle(s), connected(s.connected), listening(s.listening), writeclosed(s.writeclosed), readclosed(s.readclosed) { +Socket::Socket(const Socket & s) : Handle(s), connected(s.connected), listening(s.listening), writeclosed(s.writeclosed), readclosed(s.readclosed), connecting(s.connecting) { // cerr << "Constructing a socket by copy...\n"; // cerr << "Socket(const Socket &): connected = " << connected << "; readclosed = " << readclosed << "; writeclosed = " << writeclosed << endl; } -Socket::Socket(int h) : Handle(h), connected(true), listening(false), writeclosed(false), readclosed(false) { } +Socket::Socket(int h) : Handle(h), connected(true), listening(false), writeclosed(false), readclosed(false), connecting(false) { } String Socket::GetName(void) { return String("socket"); @@ -57,6 +57,10 @@ bool Socket::IsConnected(void) { return connected; } +bool Socket::IsConnecting(void) { + return connecting; +} + bool Socket::IsListening(void) { return listening; } @@ -139,7 +143,14 @@ bool Socket::Connect(const String & host, int port) { // cerr << " - Connected." << endl; connected = true; } else { -// cerr << " - Error connecting: " << strerror(errno) << endl; +// std::cerr << " - Error connecting: " << strerror(errno) << std::endl; +#ifdef _WIN32 + if (WSAGetLastError() == WSAEWOULDBLOCK) { +#else + if (errno == EINPROGRESS) { +#endif + connecting = true; + } } } return connected; @@ -180,6 +191,20 @@ int Socket::GetPort() { return r; } +bool Socket::FinalizeConnect() { + int r; + socklen_t l = sizeof(r); + + if (getsockopt(GetHandle(), SOL_SOCKET, SO_ERROR, (char *)&r, &l) == 0) { + if (r == 0) { + connected = true; + } + } + connecting = false; + + return connected; +} + ssize_t Socket::nwrite(const void * buf, size_t count) throw (GeneralException) { return ::send(GetHandle(), (const char *) buf, count, 0); } |