00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "stdafx.h"
00012
00013 #include "ippdme/Socket/ippSocket.h"
00014 #include "ippdme/assert.h"
00015 #include "ippdme/winsock.h"
00016
00017 #pragma comment(lib,"wsock32.lib")
00018 #pragma comment(lib,"Ws2_32.lib") // because we use W32 WS extensions
00019 #include <iostream>
00020 using namespace std;
00021
00022 static void getErrorString(int* errCode,std::string& errMsg);
00023
00024 class ippSocketImpVerification
00025 {
00026 public:
00027 ippSocketImpVerification()
00028 {
00029 IPP_ASSERT(ippSocket::SOCKET_OK == 0);
00030 IPP_ASSERT(ippSocket::SOCKET_WOULD_BLOCK == WSAEWOULDBLOCK);
00031 IPP_ASSERT(ippSocket::SOCKET_IS_CONNECTED == WSAEISCONN);
00032 }
00033 } assert;
00034
00035 class ippSocketImp
00036 {
00037 public:
00038 ippSocketImp();
00039
00040 LPHOSTENT _lpHostEntry;
00041 SOCKET _theSocket;
00042 SOCKADDR_IN _saServer;
00043 int _portNumber;
00044 WSAEVENT _Event;
00045
00046 mutable std::string _lastErrorMsg;
00047 mutable int _lastError;
00048
00049
00051 ippSocket::SERROR SetNonBlocking();
00052
00054 ippSocket::SERROR SetHostName(const char *hostName);
00055
00057 void SetPortNumber(int portNumber);
00058
00059 ippSocket::SERROR Connect();
00060 ippSocket::SERROR CanSendData();
00061 ippSocket::SERROR Read(char* buffer,int nb);
00062 ippSocket::SERROR Write(const char *sendbuf);
00063 ippSocket::SERROR Ping();
00064 bool Listen(int portNumber);
00065 ippSocket::SERROR Accept(ippSocket& socket);
00066 void Close();
00067 bool Create();
00068 private:
00069 ippSocketImp(const ippSocketImp&);
00070 void operator=(const ippSocketImp&);
00071
00072 };
00073
00074
00075
00076
00077
00078 ippSocketImp::ippSocketImp()
00079 : _theSocket(INVALID_SOCKET)
00080 , _lastError(0)
00081 , _lpHostEntry(0)
00082 , _portNumber(1294)
00083 , _Event(WSA_INVALID_EVENT)
00084 {
00085 memset(&_saServer,0,sizeof(_saServer));
00086 }
00087
00088
00089
00090 ippSocket::ippSocket()
00091 :_imp(new ippSocketImp())
00092 {
00093 }
00094
00095
00096
00097 ippSocket::~ippSocket()
00098 {
00099 Close();
00100 }
00101
00102
00103
00104
00105
00106 ippSocket::SERROR ippSocketImp::SetNonBlocking()
00107 {
00108 unsigned long arg = 1;
00109 if (ioctlsocket(_theSocket, FIONBIO, &arg)<0) {
00110 getErrorString(&_lastError,_lastErrorMsg);;
00111 return (ippSocket::SERROR)_lastError;
00112 } else {
00113 return (ippSocket::SERROR)0;
00114 }
00115
00116 }
00117
00118
00119
00120
00121 ippSocket::SERROR ippSocket::Connect(const char* hostname,int port)
00122 {
00123 IPP_ASSERT(IsValid());
00124
00125 _imp->SetHostName(hostname);
00126 _imp->SetPortNumber(port);
00127 _imp->SetNonBlocking();
00128
00129 return _imp->Connect();
00130 }
00131
00132 ippSocket::SERROR ippSocketImp::Connect()
00133 {
00134 int nRet;
00135 linger lingerOption;
00136 lingerOption.l_onoff = 0;
00137 lingerOption.l_linger = 0;
00138 nRet = setsockopt(_theSocket,SOL_SOCKET,SO_LINGER,(char*)&lingerOption,sizeof(lingerOption));
00139 if (nRet ==SOCKET_ERROR) {
00140 getErrorString(&_lastError,_lastErrorMsg);
00141 }
00142
00143
00144 nRet = connect(_theSocket,
00145 (LPSOCKADDR)&_saServer,
00146 sizeof(struct sockaddr));
00147
00148
00149 if (nRet == SOCKET_ERROR) {
00150 if (WSAEWOULDBLOCK == WSAGetLastError()){
00151 return ippSocket::SOCKET_WOULD_BLOCK;
00152 }
00153 getErrorString(&_lastError,_lastErrorMsg);
00154 return ippSocket::SOCKET_OTHER_ERROR;
00155 } else {
00156 return ippSocket::SOCKET_OK;
00157 }
00158 }
00159
00160
00161
00162
00163 ippSocket::SERROR ippSocket::CanSendData()
00164 {
00165 return _imp->CanSendData();
00166 }
00167
00168 ippSocket::SERROR ippSocketImp::CanSendData()
00169 {
00170 fd_set w;
00171 FD_ZERO(&w);
00172 FD_SET(_theSocket,&w);
00173 fd_set e;
00174 FD_ZERO(&e);
00175 FD_SET(_theSocket,&e);
00176 timeval t;
00177 t.tv_sec =0;
00178 t.tv_usec = 0;
00179 int nRet = select(0,0,&w,&e,&t);
00180 switch(nRet) {
00181 case SOCKET_ERROR :
00182
00183 getErrorString(&_lastError,_lastErrorMsg);
00184 return ippSocket::SOCKET_OTHER_ERROR;
00185 break;
00186 case 1:
00187
00188 nRet = send(_theSocket,"",0,0);
00189 if (nRet!=0) {
00190 getErrorString(&_lastError,_lastErrorMsg);
00191 return ippSocket::SOCKET_OTHER_ERROR;
00192 }
00193 return ippSocket::SOCKET_OK;
00194 break;
00195 case 0:
00196 return ippSocket::SOCKET_WOULD_BLOCK;
00197 }
00198 getErrorString(&_lastError,_lastErrorMsg);
00199 return ippSocket::SOCKET_OTHER_ERROR;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209 ippSocket::SERROR ippSocket::Read(char* buffer,int nb)
00210 {
00211 return _imp->Read(buffer,nb);
00212 }
00213
00214 ippSocket::SERROR ippSocketImp::Read(char* buffer,int nb)
00215 {
00216
00217 buffer[0]=0;
00218 int nRead = recv(_theSocket,
00219 buffer,
00220 nb,0
00221 );
00222
00223 buffer[nRead]=0;
00224 if (nRead == 0 ){
00225
00226 return ippSocket::SOCKET_OK;
00227 }
00228 if (nRead == SOCKET_ERROR) {
00229 if ( WSAEWOULDBLOCK == WSAGetLastError() ) {
00230 _lastError = WSAEWOULDBLOCK;
00231 return ippSocket::SOCKET_WOULD_BLOCK;
00232 }
00233 getErrorString(&_lastError,_lastErrorMsg);
00234 Close();
00235 return ippSocket::SOCKET_OTHER_ERROR;
00236 } else {
00237 return ippSocket::SOCKET_OK;
00238 }
00239 }
00240
00241
00242
00243
00244
00245
00246 ippSocket::SERROR ippSocket::Write(const char *sendbuf)
00247 {
00248 return _imp->Write(sendbuf);
00249 }
00250 ippSocket::SERROR ippSocketImp::Write(const char *sendbuf)
00251 {
00252
00253 int nRet = send(_theSocket,
00254 sendbuf,
00255 strlen(sendbuf),
00256 0);
00257
00258 if (nRet == SOCKET_ERROR) {
00259 getErrorString(&_lastError,_lastErrorMsg);
00260 return ippSocket::SOCKET_OTHER_ERROR;
00261 } else {
00262 return ippSocket::SOCKET_OK;
00263 }
00264 }
00265
00266
00267
00268
00269 ippSocket::SERROR ippSocketImp::SetHostName(const char *hostName)
00270 {
00271 _lpHostEntry = gethostbyname(hostName);
00272 if (_lpHostEntry == NULL) {
00273 return ippSocket::SOCKET_OTHER_ERROR;
00274 }
00275 else {
00276
00277 _saServer.sin_family = AF_INET;
00278 _saServer.sin_addr = *((LPIN_ADDR)*_lpHostEntry->h_addr_list);
00279
00280 return ippSocket::SOCKET_OK;
00281 }
00282 }
00283
00284
00285
00286
00287 void ippSocketImp::SetPortNumber(int portNumber)
00288 {
00289 _portNumber = portNumber;
00290 _saServer.sin_port = htons(_portNumber);
00291
00292 }
00293
00297 bool ippSocket::Create()
00298 {
00299 return _imp->Create();
00300 }
00301
00302 bool InitSocket()
00303 {
00304
00305 WSADATA wsaData;
00306 WORD wVersionRequested = MAKEWORD(1, 1);
00307 int nResult = WSAStartup(wVersionRequested, &wsaData);
00308 if (nResult != 0)
00309 return false;
00310
00311 if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
00312 {
00313 WSACleanup();
00314 return false;
00315 }
00316 return true;
00317 }
00318
00319
00320 bool ippSocketImp::Create()
00321 {
00322 IPP_ASSERT(_theSocket==INVALID_SOCKET && "Socket already created");
00323
00324 _theSocket = socket(AF_INET,
00325 SOCK_STREAM,
00326 IPPROTO_TCP);
00327
00328 if (_theSocket == INVALID_SOCKET) {
00329
00330 InitSocket();
00331 _theSocket = socket(AF_INET,
00332 SOCK_STREAM,
00333 IPPROTO_TCP);
00334 }
00335
00336 if (_theSocket == INVALID_SOCKET) {
00337 return FALSE;
00338 }
00339
00340
00341 _Event = WSACreateEvent();
00342 IPP_ASSERT(_Event!=WSA_INVALID_EVENT);
00343
00344
00345
00346 int nRet = WSAEventSelect(_theSocket, _Event, FD_CLOSE);
00347 IPP_ASSERT(nRet==0 && " SOCKET_ERROR ?");
00348
00349 return _theSocket != INVALID_SOCKET;
00350
00351 }
00352
00353
00357 void ippSocket::Close()
00358 {
00359 _imp->Close();
00360 }
00361
00362 void ippSocketImp::Close()
00363 {
00364 if (_theSocket !=INVALID_SOCKET) {
00365 shutdown(_theSocket,2);
00366 int nRet = closesocket(_theSocket);
00367 _theSocket =INVALID_SOCKET;
00368 }
00369 if (_Event!= WSA_INVALID_EVENT) {
00370 BOOL bRet = WSACloseEvent(_Event);
00371 IPP_ASSERT(bRet);
00372 _Event = WSA_INVALID_EVENT;
00373 }
00374 }
00375
00382 ippSocket::SERROR ippSocket::Ping()
00383 {
00384 return _imp->Ping();
00385 }
00386
00387 ippSocket::SERROR ippSocketImp::Ping()
00388 {
00389 IPP_ASSERT(_Event!=WSA_INVALID_EVENT);
00390 UINT nRet = WSAWaitForMultipleEvents(1,&_Event,TRUE,0,FALSE);
00391 IPP_ASSERT(nRet!=WSA_WAIT_FAILED);
00392 if (nRet == WSA_WAIT_TIMEOUT) {
00393 return ippSocket::SOCKET_OK;
00394 }
00395 getErrorString(&_lastError,_lastErrorMsg);
00396 return ippSocket::SOCKET_CONNECTION_ABORTED;
00397 }
00398
00404 bool ippSocket::Initialize()
00405 {
00406 WORD wVersionRequested = MAKEWORD(1,1);
00407 WSADATA wsaData;
00408 int nRet;
00409
00410
00411
00412 nRet = WSAStartup(wVersionRequested, &wsaData);
00413 if (wsaData.wVersion != wVersionRequested){
00414 return false;
00415 }
00416 return true;
00417 }
00418
00419
00420
00421
00422
00423
00424
00429 bool ippSocket::Listen(int portNumber)
00430 {
00431 return _imp->Listen(portNumber);
00432 }
00433
00434 bool ippSocketImp::Listen(int portNumber)
00435 {
00436 IPP_ASSERT(_theSocket == INVALID_SOCKET);
00437 _theSocket = socket(AF_INET,
00438 SOCK_STREAM,
00439 IPPROTO_TCP);
00440
00441
00442 if(_theSocket == INVALID_SOCKET) {
00443 InitSocket();
00444 _theSocket = socket(AF_INET,
00445 SOCK_STREAM,
00446 IPPROTO_TCP);
00447
00448 if(_theSocket == INVALID_SOCKET) {
00449 getErrorString(&_lastError,_lastErrorMsg);
00450 IPP_ASSERT_FAIL("Cannot create socket");
00451 return false;
00452 }
00453 }
00454 _portNumber = portNumber;
00455 _saServer.sin_family = AF_INET;
00456 _saServer.sin_addr.s_addr = INADDR_ANY;
00457 _saServer.sin_port = htons(_portNumber);
00458
00459
00460
00461
00462 int nRet = bind(_theSocket,
00463 (LPSOCKADDR)&_saServer,
00464 sizeof(struct sockaddr));
00465
00466 if (nRet == SOCKET_ERROR)
00467 {
00468 getErrorString(&_lastError,_lastErrorMsg);
00469 Close();
00470 return false;
00471 }
00472
00473
00474 unsigned long arg = 1;
00475 if (ioctlsocket(_theSocket, FIONBIO, &arg)<0)
00476 {
00477 getErrorString(&_lastError,_lastErrorMsg);
00478 Close();
00479 return false;
00480 }
00481
00482
00483
00484 int request_in_queue = 0;
00485 nRet = ::listen(_theSocket,request_in_queue);
00486
00487 if (nRet == SOCKET_ERROR) {
00488 getErrorString(&_lastError,_lastErrorMsg);
00489 Close();
00490 return false;
00491 }
00492
00493
00494 char szBuf[1000] = "";
00495 nRet = gethostname(szBuf, sizeof(szBuf));
00496 if (nRet == SOCKET_ERROR)
00497 {
00498 int err = WSAGetLastError();
00499 Close();
00500 return false;
00501 }
00502
00503
00504 return true;
00505 }
00506
00507
00508
00519 ippSocket::SERROR ippSocket::Accept(ippSocket& socket)
00520 {
00521 return _imp->Accept(socket);
00522 }
00523
00524 ippSocket::SERROR ippSocketImp::Accept(ippSocket& socket)
00525 {
00526 IPP_ASSERT(!socket.IsValid());
00527
00528 SOCKET sock = accept(_theSocket,
00529 NULL,
00530 NULL);
00531
00532 if (sock == INVALID_SOCKET){
00533 _lastError = WSAGetLastError();
00534 if (WSAEWOULDBLOCK == _lastError ){
00535 return ippSocket::SOCKET_WOULD_BLOCK;
00536 } else {
00537 getErrorString(&_lastError,_lastErrorMsg);;
00538 Close();
00539 return ippSocket::SOCKET_OTHER_ERROR;
00540 }
00541 }
00542 socket._imp->_theSocket = sock;
00543 IPP_ASSERT(socket._imp->_Event==WSA_INVALID_EVENT);
00544 socket._imp->_Event = WSACreateEvent();
00545
00546
00547
00548
00549 WSAEventSelect(socket._imp->_theSocket, socket._imp->_Event, FD_CLOSE);
00550
00551 return ippSocket::SOCKET_OK;
00552 }
00553
00554
00560 bool ippSocket::IsValid() const
00561 {
00562 return _imp->_theSocket!= INVALID_SOCKET;
00563 }
00564
00565
00566 void getErrorString(int* errCode,string& errMsg)
00572 {
00573 *errCode = WSAGetLastError();
00574 errMsg ="";
00575 switch(*errCode) {
00576 case WSANOTINITIALISED:
00577 errMsg.append("Successful WSAStartup must occur before using this function.");
00578 break;
00579 case WSAENETDOWN:
00580 errMsg.append("The network subsystem or the associated service provider has failed.");
00581 break;
00582 case WSAEAFNOSUPPORT:
00583 errMsg.append("The specified address family is not supported.");
00584 break;
00585 case WSAEINPROGRESS:
00586 errMsg.append("A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.");
00587 break;
00588 case WSAEMFILE:
00589 errMsg.append("No more socket descriptors are available.");
00590 break;
00591 case WSAENOBUFS:
00592 errMsg.append("No buffer space is available. The socket cannot be created.");
00593 break;
00594 case WSAEPROTONOSUPPORT:
00595 errMsg.append("The specified protocol is not supported.");
00596 break;
00597 case WSAEPROTOTYPE:
00598 errMsg.append("The specified protocol is the wrong type for this socket.");
00599 break;
00600 case WSAESOCKTNOSUPPORT:
00601 errMsg.append("The specified socket type is not supported in this address family.");
00602 break;
00603 case WSAEINVAL:
00604 errMsg.append("level is not valid, or the information in optval is not valid.");
00605 break;
00606 case WSAENETRESET:
00607 errMsg.append("Connection has timed out when SO_KEEPALIVE is set.");
00608 break;
00609 case WSAENOPROTOOPT:
00610 errMsg.append("The option is unknown or unsupported for the specified provider or socket (see SO_GROUP_PRIORITY limitations).");
00611 break;
00612 case WSAENOTCONN:
00613 errMsg.append("Connection has been reset when SO_KEEPALIVE is set.");
00614 break;
00615 case WSAENOTSOCK:
00616 errMsg.append("The descriptor is not a socket.");
00617 break;
00618 case WSAEADDRINUSE:
00619 errMsg.append("A process on the machine is already bound to the same\n");
00620 errMsg.append("fully-qualified address and the socket has not been marked\n");
00621 errMsg.append("to allow address re-use with SO_REUSEADDR. For example,\n");
00622 errMsg.append("IP address and port are bound in the af_inet case");
00623 break;
00624 case WSAEWOULDBLOCK:
00625 errMsg.append("WSAEWOULDBLOCK");
00626 break;
00627 case WSAECONNABORTED:
00628 errMsg.append("Connection aborted");
00629 break;
00630 default:
00631 errMsg.append("unknown problems!");
00632 }
00633 }
00634
00635
00636 IPPDME_EXT_CLASS void ippSleep(int time_in_milisecond)
00637 {
00638 ::Sleep(time_in_milisecond);
00639 }