00001
00002 #ifndef __SOCKETS_WIN32_PAL_HPP__
00003 #define __SOCKETS_WIN32_PAL_HPP__
00004
00005 #include <winsock2.h>
00006 #include <string.h>
00007 #include <assert.h>
00008
00009 namespace lfc
00010 {
00011 namespace win32PAL
00012 {
00013
00015 namespace sockets
00016 {
00017
00018 const int MAX_ERROR_CODE = 6;
00019
00020 enum ErrorCodes
00021 {
00022 errOk,
00023 errGeneric,
00024 errInitError,
00025 errConnectionClosed,
00026 errUnbound,
00027 errNotListening,
00028 errBadAddress
00029 };
00030
00031 extern const char *messagesTable[MAX_ERROR_CODE + 1];
00032
00033
00035 const int
00036 pfINET = AF_INET,
00037 pfUNIX = AF_UNIX,
00038 pfIPX = AF_IPX;
00039
00041 const int
00042 stSTREAM = SOCK_STREAM,
00043 stDGRAM = SOCK_DGRAM;
00044
00046 const int
00047 flagPEEK = MSG_PEEK,
00048 flagOOB = MSG_OOB;
00049
00050
00052 typedef SOCKET Handle;
00053
00055 const Handle NULL_HANDLE = INVALID_SOCKET;
00056
00057
00059
00063 inline int init()
00064 {
00065 WSADATA wsad;
00066
00067 switch( ::WSAStartup(0x0002, &wsad) )
00068 {
00069 case errOk:
00070 return errOk;
00071
00072 case WSAVERNOTSUPPORTED:
00073 return errInitError;
00074
00075 default:
00076 return errGeneric;
00077 }
00078 }
00079
00081
00085 inline int cleanup()
00086 {
00087 ::WSASetLastError(0);
00088 if( ::WSACleanup() == SOCKET_ERROR )
00089 if( ::WSAGetLastError() == WSANOTINITIALISED )
00090 return errInitError;
00091 else
00092 return errGeneric;
00093
00094 return errOk;
00095 }
00096
00098
00105 inline int open(Handle &handle, int pf, int type)
00106 {
00107 Handle temp;
00108 ::WSASetLastError(0);
00109 if((temp = ::socket(pf, type, 0)) == INVALID_SOCKET)
00110 if( ::WSAGetLastError() == WSANOTINITIALISED )
00111 return errInitError;
00112 else
00113 return errGeneric;
00114
00115 handle = temp;
00116 return errOk;
00117 }
00118
00120
00124 inline int close(Handle handle)
00125 {
00126 ::WSASetLastError(0);
00127 if( ::shutdown(handle, SD_BOTH) == SOCKET_ERROR )
00128 if( ::WSAGetLastError() == WSANOTINITIALISED )
00129 return errInitError;
00130 else
00131 return errGeneric;
00132
00133 ::WSASetLastError(0);
00134 if( ::closesocket(handle) == SOCKET_ERROR )
00135 if( ::WSAGetLastError() == WSANOTINITIALISED )
00136 return errInitError;
00137 else
00138 return errGeneric;
00139
00140 return errOk;
00141 }
00142
00144
00153 inline int connect(Handle handle, const char* to, int pf,
00154 u_short port)
00155 {
00156 sockaddr_in sin;
00157 hostent *hp = ::gethostbyname(to);
00158
00159 if( hp == NULL )
00160 if( ( sin.sin_addr.s_addr = inet_addr(to) ) == INADDR_NONE )
00161 return errBadAddress;
00162 else
00163 ::memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
00164
00165 sin.sin_family = pf;
00166 sin.sin_port = htons(port);
00167
00168 ::WSASetLastError(0);
00169 if( ::connect(handle, (sockaddr *)&sin, sizeof sin) == SOCKET_ERROR )
00170 if( ::WSAGetLastError() == WSANOTINITIALISED )
00171 return errInitError;
00172 else
00173 return errGeneric;
00174
00175 return errOk;
00176 }
00177
00179
00189 inline int send(Handle handle, const char* buffer, long len, int flags,
00190 long &bytesSent)
00191 {
00192 ::WSASetLastError(0);
00193 if( ( bytesSent = ::send(handle, buffer, len, flags)) == SOCKET_ERROR )
00194 switch( ::WSAGetLastError() )
00195 {
00196 case WSANOTINITIALISED:
00197 return errInitError;
00198
00199 case WSAEINVAL:
00200 return errUnbound;
00201
00202 default:
00203 return errGeneric;
00204 }
00205
00206 return errOk;
00207 }
00208
00209
00227 inline int sendTo(Handle handle, const char* buffer, long len, int flags,
00228 const char* to, int pf, u_short port,
00229 long &bytesSent)
00230 {
00231 sockaddr_in sin;
00232 hostent *hp = ::gethostbyname(to);
00233
00234 if( hp == NULL )
00235 if( ( sin.sin_addr.s_addr = inet_addr(to) ) == INADDR_NONE )
00236 return errBadAddress;
00237 else
00238 ::memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
00239
00240 sin.sin_family = pf;
00241 sin.sin_port = htons(port);
00242
00243 ::WSASetLastError(0);
00244 bytesSent = ::sendto(handle, buffer, len, flags, (sockaddr *)&sin,
00245 sizeof sin);
00246
00247 if( bytesSent == SOCKET_ERROR )
00248 switch( ::WSAGetLastError() )
00249 {
00250 case WSANOTINITIALISED:
00251 return errInitError;
00252
00253 default:
00254 return errGeneric;
00255 }
00256
00257 return errOk;
00258 }
00259
00260
00262
00270 inline int recv(Handle handle, char* buffer, long len, int flags,
00271 long &bytesReceived)
00272 {
00273 ::WSASetLastError(0);
00274 switch( bytesReceived = ::recv(handle, buffer, len, flags) )
00275 {
00276 case 0:
00277 return errConnectionClosed;
00278
00279 case SOCKET_ERROR:
00280 switch( ::WSAGetLastError() )
00281 {
00282 case WSANOTINITIALISED:
00283 return errInitError;
00284
00285 case WSAEINVAL:
00286 return errUnbound;
00287
00288 default:
00289 return errGeneric;
00290 }
00291
00292 default:
00293 return errOk;
00294 }
00295 }
00296
00297
00299
00311 inline int recvFrom(Handle handle, char* buffer, long len, int flags,
00312 char* from, int pf, u_short port,
00313 long &bytesReceived)
00314 {
00315 sockaddr_in sin;
00316
00317 int sinSize = sizeof sin;
00318
00319 ::WSASetLastError(0);
00320 bytesReceived = ::recvfrom(handle, buffer, len, flags, (sockaddr *)&sin,
00321 &sinSize);
00322
00323 switch( bytesReceived )
00324 {
00325 case 0:
00326 return errConnectionClosed;
00327
00328 case SOCKET_ERROR:
00329 switch( ::WSAGetLastError() )
00330 {
00331 case WSANOTINITIALISED:
00332 return errInitError;
00333
00334 default:
00335 return errGeneric;
00336 }
00337
00338 default:
00339 ::strcpy(from, ::inet_ntoa(sin.sin_addr));
00340 return errOk;
00341 }
00342 }
00343
00345
00352 inline int bind(Handle handle, int pf, u_short port)
00353 {
00354 sockaddr_in sin;
00355
00356 sin.sin_addr.s_addr = INADDR_ANY;
00357 sin.sin_port = htons(port);
00358 sin.sin_family = pf;
00359
00360 ::WSASetLastError(0);
00361 if( ::bind(handle, (sockaddr *)&sin, sizeof sin) == SOCKET_ERROR )
00362 if( ::WSAGetLastError() == WSANOTINITIALISED )
00363 return errInitError;
00364 else
00365 return errGeneric;
00366
00367 return errOk;
00368 }
00369
00371
00377 inline int listen(Handle handle, int backlog = SOMAXCONN)
00378 {
00379 ::WSASetLastError(0);
00380 if( ::listen(handle, backlog) == SOCKET_ERROR )
00381 switch( ::WSAGetLastError() )
00382 {
00383 case WSANOTINITIALISED:
00384 return errInitError;
00385
00386 case WSAEINVAL:
00387 return errUnbound;
00388
00389 default:
00390 return errGeneric;
00391 }
00392
00393 return errOk;
00394 }
00395
00397
00403 inline int accept(Handle& newHandle, Handle handle)
00404 {
00405 Handle temp;
00406 ::WSASetLastError(0);
00407 if(( temp = ::accept(handle, NULL, NULL) ) == INVALID_SOCKET)
00408 switch( ::WSAGetLastError() )
00409 {
00410 case WSANOTINITIALISED:
00411 return errInitError;
00412
00413 case WSAEINVAL:
00414 return errNotListening;
00415
00416 default:
00417 return errGeneric;
00418 }
00419
00420 newHandle = temp;
00421 return errOk;
00422 }
00423
00425
00430 inline int setBlocking(Handle handle, bool blocking)
00431 {
00432 u_long state = blocking ? 0 : 1;
00433 ::WSASetLastError(0);
00434 if( ::ioctlsocket(handle, FIONBIO, &state) == SOCKET_ERROR )
00435 if( ::WSAGetLastError() == WSANOTINITIALISED )
00436 return errInitError;
00437 else
00438 return errGeneric;
00439
00440 return errOk;
00441 }
00442
00443
00449 inline int getServicePort(const char *service, u_short &port)
00450 {
00451 servent *psent = ::getservbyname(service, NULL);
00452 if(psent == NULL)
00453 return errGeneric;
00454 port = ::ntohs(psent->s_port);
00455 return errOk;
00456 }
00457
00458
00460
00465 inline int flush(Handle handle)
00466 {
00467 return errOk;
00468 }
00469
00470
00472 inline const char *message(int index)
00473 {
00474 assert(index >= 0 && index <= MAX_ERROR_CODE);
00475 return messagesTable[index];
00476 }
00477
00478
00479 }
00480 }
00481
00482 namespace pal = win32PAL;
00483
00484 }
00485
00486 #endif // __SOCKETS_WIN32_PAL_HPP__
00487