00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifdef WIN32
00035 #include "JSocket.h"
00036
00037 namespace cmlabs {
00038
00039 #ifndef CYGWIN
00040 #define null NULL
00041 #else
00042 #define null 0
00043 #endif
00044
00045 void JSocket::osCloseSocket(SOCKET thisSocket) {
00046
00047 if (shutdown(thisSocket, SD_BOTH) < 0)
00048 connected = connected;
00049
00050 if (closesocket(thisSocket) < 0)
00051 connected = connected;
00052 }
00053
00054 bool JSocket::isSocketValid() {
00055
00056
00057 if (this == NULL)
00058 return false;
00059 if (mySocket == null)
00060 return false;
00061 else
00062 return true;
00063 }
00064
00065 bool JSocket::setSocketNotValid() {
00066 mySocket = 0;
00067 return true;
00068 }
00069
00070 void JSocket::setNonBlockingMode() {
00071 unsigned long parm = 1;
00072 ioctlsocket(mySocket, FIONBIO, &parm);
00073 }
00074
00075 void JSocket::setBlockingMode() {
00076 unsigned long parm = 0;
00077 ioctlsocket(mySocket, FIONBIO, &parm);
00078 }
00079
00080
00081 bool JSocket::createSocket() {
00082 if (mySocket == null) {
00083 mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00084 if (mySocket == INVALID_SOCKET) {
00085
00086 int wsaError = getLastOSErrorNumber();
00087 if (wsaError == WSANOTINITIALISED) {
00088 WSADATA info;
00089 if (WSAStartup(MAKEWORD(1,1), &info) != 0) {
00090 dealWithSocketError(wsaError);
00091 mySocket = null;
00092 return false;
00093 }
00094 else {
00095
00096 mySocket = socket(AF_INET, SOCK_STREAM, 0);
00097 if (mySocket == INVALID_SOCKET)
00098 wsaError = getLastOSErrorNumber();
00099 }
00100 }
00101
00102
00103 if (mySocket == INVALID_SOCKET) {
00104 dealWithSocketError(wsaError);
00105 mySocket = null;
00106 return false;
00107 }
00108 }
00109 }
00110
00111
00112 setNonBlockingMode();
00113
00114
00115
00116
00117
00118
00119
00120
00121 struct linger tmp = {1, 0};
00122 setsockopt(mySocket, SOL_SOCKET, SO_LINGER, (char *)&tmp, sizeof(tmp));
00123
00124 char delay = 1;
00125 setsockopt(mySocket, IPPROTO_TCP, TCP_NODELAY, (char*) &delay, sizeof(delay));
00126
00127
00128 return true;
00129 }
00130
00131
00132 void JSocket::dealWithSocketError(int wsaError, JString intro) {
00133
00134 if (wsaError == WSANOTINITIALISED) {
00135 lastErrorMessage = "Cannot initialize WinSock!";
00136 lastErrorRecoverable = false;
00137 }
00138 else if (wsaError == WSAENETDOWN) {
00139 lastErrorMessage = "The network subsystem or the associated service provider has failed";
00140 lastErrorRecoverable = false;
00141 }
00142 else if (wsaError == WSAEAFNOSUPPORT) {
00143 lastErrorMessage = "The specified address family is not supported";
00144 lastErrorRecoverable = false;
00145 }
00146 else if (wsaError == WSAEINPROGRESS) {
00147 lastErrorMessage = "A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function";
00148 lastErrorRecoverable = true;
00149 }
00150 else if (wsaError == WSAEMFILE) {
00151 lastErrorMessage = "No more socket descriptors are available";
00152 lastErrorRecoverable = false;
00153 }
00154 else if (wsaError == WSAENOBUFS) {
00155 lastErrorMessage = "No buffer space is available. The socket cannot be created";
00156 lastErrorRecoverable = false;
00157 }
00158 else if (wsaError == WSAEPROTONOSUPPORT) {
00159 lastErrorMessage = "The specified protocol is not supported";
00160 lastErrorRecoverable = false;
00161 }
00162 else if (wsaError == WSAEPROTOTYPE) {
00163 lastErrorMessage = "The specified protocol is the wrong type for this socket";
00164 lastErrorRecoverable = false;
00165 }
00166 else if (wsaError == WSAESOCKTNOSUPPORT) {
00167 lastErrorMessage = "The specified socket type is not supported in this address family";
00168 lastErrorRecoverable = false;
00169 }
00170 else if (wsaError == WSAEADDRINUSE) {
00171 lastErrorMessage = "The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs during execution of the bind function, but could be delayed until this function if the bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function";
00172 lastErrorRecoverable = false;
00173 }
00174 else if (wsaError == WSAEINVAL) {
00175 lastErrorMessage = "The socket has not been bound with bind";
00176 lastErrorRecoverable = false;
00177 }
00178 else if (wsaError == WSAEISCONN) {
00179 lastErrorMessage = "The socket is already connected";
00180 lastErrorRecoverable = false;
00181 }
00182 else if (wsaError == WSAENOTSOCK) {
00183 lastErrorMessage = "The descriptor is not a socket";
00184 lastErrorRecoverable = false;
00185 }
00186 else if (wsaError == WSAEOPNOTSUPP) {
00187 lastErrorMessage = "The referenced socket is not of a type that supports the listen operation";
00188 lastErrorRecoverable = false;
00189 }
00190 else if (wsaError == WSAEADDRNOTAVAIL) {
00191 lastErrorMessage = "The specified address is not a valid address for this machine";
00192 lastErrorRecoverable = false;
00193 }
00194 else if (wsaError == WSAEFAULT) {
00195 lastErrorMessage = "The name or namelen parameter is not a valid part of the user address space, the namelen parameter is too small, the name parameter contains an incorrect address format for the associated address family, or the first two bytes of the memory block specified by name does not match the address family associated with the socket descriptor s";
00196 lastErrorRecoverable = false;
00197 }
00198 else if (wsaError == WSAEMFILE) {
00199 lastErrorMessage = "The queue is nonempty upon entry to accept and there are no descriptors available";
00200 lastErrorRecoverable = false;
00201 }
00202 else if (wsaError == WSAEWOULDBLOCK) {
00203 lastErrorMessage = "The socket is marked as nonblocking and no connections are present to be accepted";
00204 lastErrorRecoverable = false;
00205 }
00206 else if (wsaError == WSAETIMEDOUT) {
00207 lastErrorMessage = "Attempt to connect timed out without establishing a connection";
00208 lastErrorRecoverable = false;
00209 }
00210 else if (wsaError == WSAENETUNREACH) {
00211 lastErrorMessage = "The network cannot be reached from this host at this time";
00212 lastErrorRecoverable = false;
00213 }
00214 else if (wsaError == WSAEISCONN) {
00215 lastErrorMessage = "The socket is already connected (connection-oriented sockets only)";
00216 lastErrorRecoverable = false;
00217 }
00218 else if (wsaError == WSAECONNREFUSED) {
00219 lastErrorMessage = "The attempt to connect was forcefully rejected";
00220 lastErrorRecoverable = false;
00221 }
00222 else if (wsaError == WSAEAFNOSUPPORT) {
00223 lastErrorMessage = "Addresses in the specified family cannot be used with this socket";
00224 lastErrorRecoverable = false;
00225 }
00226 else if (wsaError == WSAEADDRNOTAVAIL) {
00227 lastErrorMessage = "The remote address is not a valid address (such as ADDR_ANY)";
00228 lastErrorRecoverable = false;
00229 }
00230 else if (wsaError == WSAEALREADY) {
00231 lastErrorMessage = "A nonblocking connect call is in progress on the specified socket";
00232 lastErrorRecoverable = false;
00233 }
00234 else if (wsaError == WSAECONNRESET) {
00235 lastErrorMessage = "Connection was reset";
00236 lastErrorRecoverable = false;
00237 }
00238 else if (wsaError == WSAECONNABORTED) {
00239 lastErrorMessage = "Software caused connection abort";
00240 lastErrorRecoverable = false;
00241 }
00242 else {
00243 lastErrorMessage = JString("TCP error with no description: ") + JString(wsaError);
00244 lastErrorRecoverable = false;
00245 }
00246
00247
00248
00249 if (intro.length() > 0)
00250 lastErrorMessage = intro + JString(": ") + lastErrorMessage;
00251
00252 if (DEBUGLEVEL(DEBUG)) {
00253 printf("Network Error: %s\n", (char*)lastErrorMessage);
00254 }
00255 }
00256
00257
00258 int JSocket::getLastOSErrorNumber() {
00259 int err = WSAGetLastError();
00260 WSASetLastError(0);
00261 return err;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 }
00320
00321 #endif // WIN32
00322
00323