diff options
author | Mike Buland <eichlan@xagasoft.com> | 2009-01-19 21:46:48 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2009-01-19 21:46:48 +0000 |
commit | 9d099f181674ae075aa8ccaeb56acc7b732638af (patch) | |
tree | a376da5671e044e74b4014d43c9125974b4dee0c /src/socket.cpp | |
parent | 8c1f4d7bace6ff2c99d546cedaba890b349e88f8 (diff) | |
download | libbu++-9d099f181674ae075aa8ccaeb56acc7b732638af.tar.gz libbu++-9d099f181674ae075aa8ccaeb56acc7b732638af.tar.bz2 libbu++-9d099f181674ae075aa8ccaeb56acc7b732638af.tar.xz libbu++-9d099f181674ae075aa8ccaeb56acc7b732638af.zip |
This should fix the problem of never knowing if your sockets are closed. Now
Bu::Socket::read will throw an exception if the socket has been closed. Also,
you'll get an exception at object creation if the socket could connect to a
computer, but not the given port.
Diffstat (limited to '')
-rw-r--r-- | src/socket.cpp | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/src/socket.cpp b/src/socket.cpp index dd19d39..3e4f3c7 100644 --- a/src/socket.cpp +++ b/src/socket.cpp | |||
@@ -115,6 +115,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) | |||
115 | close(); | 115 | close(); |
116 | throw ExceptionBase("Connection timeout.\n"); | 116 | throw ExceptionBase("Connection timeout.\n"); |
117 | } | 117 | } |
118 | read( NULL, 0 ); // See if we can get any errors out of the way early. | ||
118 | } | 119 | } |
119 | } | 120 | } |
120 | 121 | ||
@@ -129,6 +130,7 @@ void Bu::Socket::close() | |||
129 | #ifndef WIN32 | 130 | #ifndef WIN32 |
130 | fsync( nSocket ); | 131 | fsync( nSocket ); |
131 | #endif | 132 | #endif |
133 | shutdown( nSocket, SHUT_RDWR ); | ||
132 | ::close( nSocket ); | 134 | ::close( nSocket ); |
133 | } | 135 | } |
134 | bActive = false; | 136 | bActive = false; |
@@ -136,25 +138,36 @@ void Bu::Socket::close() | |||
136 | 138 | ||
137 | size_t Bu::Socket::read( void *pBuf, size_t nBytes ) | 139 | size_t Bu::Socket::read( void *pBuf, size_t nBytes ) |
138 | { | 140 | { |
139 | #ifdef WIN32 | 141 | fd_set rfds; |
140 | int nRead = TEMP_FAILURE_RETRY( | 142 | FD_ZERO(&rfds); |
141 | bu_recv( nSocket, (char *) pBuf, nBytes, 0 ) ); | 143 | FD_SET(nSocket, &rfds); |
142 | #else | 144 | struct timeval tv = {0, 0}; |
143 | int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) ); | 145 | if( bu_select( nSocket+1, &rfds, NULL, NULL, &tv ) < 0 ) |
144 | #endif | 146 | throw SocketException( SocketException::cRead, strerror(errno) ); |
145 | if( nRead < 0 ) | 147 | if( FD_ISSET( nSocket, &rfds ) ) |
146 | { | 148 | { |
149 | int nRead = TEMP_FAILURE_RETRY( | ||
150 | bu_recv( nSocket, (char *) pBuf, nBytes, 0 ) ); | ||
151 | if( nRead == 0 ) | ||
152 | { | ||
153 | bActive = false; | ||
154 | throw SocketException( SocketException::cClosed, "Socket closed."); | ||
155 | } | ||
156 | if( nRead < 0 ) | ||
157 | { | ||
147 | #ifdef WIN32 | 158 | #ifdef WIN32 |
148 | int iWSAError = bu_WSAGetLastError(); | 159 | int iWSAError = bu_WSAGetLastError(); |
149 | if( iWSAError == WSAEWOULDBLOCK ) | 160 | if( iWSAError == WSAEWOULDBLOCK ) |
150 | return 0; | 161 | return 0; |
151 | #else | 162 | #else |
152 | if( errno == EAGAIN ) | 163 | if( errno == EAGAIN ) |
153 | return 0; | 164 | return 0; |
154 | throw SocketException( SocketException::cRead, strerror(errno) ); | 165 | throw SocketException( SocketException::cRead, strerror(errno) ); |
155 | #endif | 166 | #endif |
167 | } | ||
168 | return nRead; | ||
156 | } | 169 | } |
157 | return nRead; | 170 | return 0; |
158 | } | 171 | } |
159 | 172 | ||
160 | size_t Bu::Socket::read( void *pBuf, size_t nBytes, | 173 | size_t Bu::Socket::read( void *pBuf, size_t nBytes, |
@@ -203,12 +216,12 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes, | |||
203 | 216 | ||
204 | size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) | 217 | size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) |
205 | { | 218 | { |
206 | #ifdef WIN32 | 219 | //#ifdef WIN32 |
207 | int nWrote = TEMP_FAILURE_RETRY( | 220 | int nWrote = TEMP_FAILURE_RETRY( |
208 | bu_send( nSocket, (const char *) pBuf, nBytes, 0 ) ); | 221 | bu_send( nSocket, (const char *) pBuf, nBytes, 0 ) ); |
209 | #else | 222 | //#else |
210 | int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); | 223 | // int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); |
211 | #endif | 224 | //#endif |
212 | if( nWrote < 0 ) | 225 | if( nWrote < 0 ) |
213 | { | 226 | { |
214 | #ifdef WIN32 | 227 | #ifdef WIN32 |