00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "ezSockets.h"
00012
00013 #if defined(_MSC_VER) && !defined(_XBOX) // We need the WinSock32 Library on Windows
00014 #pragma comment(lib,"wsock32.lib")
00015 #elif !defined(__MINGW32__) && !defined(_XBOX)
00016 #include <sys/types.h>
00017 #include <sys/socket.h>
00018 #include <unistd.h>
00019 #include <arpa/inet.h>
00020 #include <netdb.h>
00021 #endif
00022
00023 #if !defined(SOCKET_ERROR)
00024 #define SOCKET_ERROR -1
00025 #endif
00026
00027
00028 #if !defined(SOCKET_NONE)
00029 #define SOCKET_NONE 0
00030 #endif
00031
00032 #if !defined(INVALID_SOCKET)
00033 #define INVALID_SOCKET -1
00034 #endif
00035
00036 #if defined(WIN32)
00037 typedef int socklen_t;
00038 #endif
00039
00040 int iPackets = 0;
00041 #include <iostream>
00042 ezSocketsPacket::ezSocketsPacket()
00043 {
00044 Data = NULL;
00045 Next = NULL;
00046 iPackets++;
00047 Port = 0;
00048 ClearPacket();
00049 }
00050
00051 ezSocketsPacket::~ezSocketsPacket()
00052 {
00053 iPackets--;
00054 if ( Data )
00055 free( Data );
00056 }
00057
00058 void ezSocketsPacket::CopyPacket( ezSocketsPacket & pPacketToCopy )
00059 {
00060 Size = pPacketToCopy.Size;
00061 if ( Data )
00062 delete Data;
00063 Data = (char*)malloc( Size );
00064 memcpy( Data, pPacketToCopy.Data, Size );
00065 Position = 0;
00066 Next = NULL;
00067 }
00068
00069 void ezSocketsPacket::DestroyTree()
00070 {
00071 if ( Next )
00072 {
00073 Next->DestroyTree();
00074 delete Next;
00075 Next = NULL;
00076 }
00077 if ( Data )
00078 {
00079 delete Data;
00080 Data = NULL;
00081 }
00082 }
00083
00084 void ezSocketsPacket::ClearPacket()
00085 {
00086 if ( Data )
00087 free( Data );
00088 Data = NULL;
00089 Position = 0;
00090 Size = 0;
00091 }
00092
00093 void ezSocketsPacket::SetupPacket( unsigned int iSize )
00094 {
00095 if ( Data )
00096 free( Data );
00097 Data = (char*)malloc( iSize );
00098 Position = 0;
00099 Size = iSize;
00100 }
00101
00102 unsigned char ezSocketsPacket::Read1()
00103 {
00104 if ( Position < Size )
00105 return Data[Position++];
00106 else
00107 return 0;
00108 }
00109
00110 unsigned short ezSocketsPacket::Read2()
00111 {
00112 if ( Position + 1 < Size )
00113 return ntohs( *((unsigned short*)&(Data[(Position+=2)-2])) );
00114 else
00115 return 0;
00116 }
00117
00118 unsigned long ezSocketsPacket::Read4()
00119 {
00120 if ( Position + 3 < Size )
00121 return ntohl( *((unsigned long*)&(Data[(Position+=4)-4])) );
00122 else
00123 return 0;
00124 }
00125
00126 MString ezSocketsPacket::ReadNT()
00127 {
00128 if ( Position >= Size )
00129 return MString("");
00130
00131 char * base = &Data[Position];
00132
00133 while ( Data[Position++] != '\0' );
00134
00135 return MString(base);
00136 }
00137
00138 void ezSocketsPacket::Write1( unsigned char Info )
00139 {
00140 Grow( Position + 1 );
00141 Data[Position++] = Info;
00142 }
00143
00144 void ezSocketsPacket::Write2( unsigned short Info )
00145 {
00146 Grow( Position + 2 );
00147 *((short*)(&Data[Position])) = htons(Info);
00148 Position+=2;
00149 }
00150
00151 void ezSocketsPacket::Write4( unsigned long Info )
00152 {
00153 Grow( Position + 4 );
00154 *((unsigned long*)(&Data[Position])) = htonl(Info);
00155 Position += 4;
00156 }
00157
00158 void ezSocketsPacket::WriteNT( const MString& Info )
00159 {
00160 Grow( Position + Info.length() + 1 );
00161 memcpy( &Data[Position], Info.c_str(), Info.length()+1 );
00162 Position += Info.length()+1;
00163 }
00164
00165 int ezSocketsPacket::ReadData( int Bytes, char * ToReplace )
00166 {
00167 if ( Bytes + Position >= Size )
00168 Bytes = (int)Size - (int)Position;
00169 if ( Bytes > 0 )
00170 memcpy( ToReplace, &Data[Position], Bytes );
00171 else
00172 return 0;
00173 Position += Bytes;
00174 return Bytes;
00175 }
00176
00177 void ezSocketsPacket::WriteData( const char * Info, unsigned int Length )
00178 {
00179 Grow( Length + Position );
00180 memcpy( &Data[Position], Info, Length );
00181 Position += Length;
00182 }
00183
00184 void ezSocketsPacket::Grow( unsigned long iSizeTo )
00185 {
00186 if ( iSizeTo > Size )
00187 {
00188 char * OldData = Data;
00189 Data = (char*)malloc( iSizeTo );
00190 if ( OldData )
00191 {
00192 memcpy( Data, OldData, Size );
00193 free( OldData );
00194 }
00195 Size = iSizeTo;
00196 }
00197 }
00198
00199 ezSockets::ezSockets()
00200 {
00201 memset (&addr,0,sizeof(addr));
00202
00203 #if defined(_WIN32) || defined(_XBOX) // Windows REQUIRES WinSock Startup
00204 WSAStartup( MAKEWORD(1,1), &wsda );
00205 #endif
00206
00207 sock = INVALID_SOCKET;
00208 bBlocking = true;
00209 scks = new fd_set;
00210 times = new timeval;
00211 times->tv_sec = 0;
00212 times->tv_usec = 0;
00213 state = skDISCONNECTED;
00214
00215 iBytesInPending = 0;
00216 pDataInTail = NULL;
00217 pDataInHead = NULL;
00218 }
00219
00220 ezSockets::~ezSockets()
00221 {
00222 Close();
00223 delete scks;
00224 delete times;
00225 }
00226
00227 bool ezSockets::Check()
00228 {
00229 #if !defined(XBOX)
00230 return sock > SOCKET_NONE;
00231 #else
00232 return sock != INVALID_SOCKET;
00233 #endif
00234 }
00235
00236 bool ezSockets::Create(int Protocol, int Type)
00237 {
00238 state = skDISCONNECTED;
00239 sock = socket(AF_INET, Type, Protocol);
00240 lastCode = sock;
00241 #if !defined(XBOX)
00242 return sock > SOCKET_NONE;
00243 #else
00244 return sock != INVALID_SOCKET;
00245 #endif
00246 }
00247
00248 bool ezSockets::Bind(unsigned short port)
00249 {
00250 if(!Check())
00251 return false;
00252
00253 addr.sin_family = AF_INET;
00254 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00255 addr.sin_port = htons(port);
00256 lastCode = ::bind(sock,(struct sockaddr*)&addr, sizeof(addr));
00257 return !lastCode;
00258 }
00259
00260 bool ezSockets::Listen( unsigned long depth )
00261 {
00262 lastCode = ::listen(sock, depth);
00263 if (lastCode == SOCKET_ERROR)
00264 return false;
00265
00266 state = skLISTENING;
00267 return true;
00268 }
00269
00270 bool ezSockets::Accept(ezSockets& socket)
00271 {
00272 if (!bBlocking && !CanRead())
00273 return false;
00274
00275 int length = sizeof(socket);
00276
00277 socket.sock = ::accept(sock,(struct sockaddr*) &socket.addr,
00278 (socklen_t*) &length);
00279
00280 #if !( defined (_WIN32) || defined( _XBOX ) )
00281 char buf[INET_ADDRSTRLEN];
00282 inet_ntop(AF_INET, &socket.addr.sin_addr, buf, INET_ADDRSTRLEN);
00283 address = buf;
00284 #else
00285 address = inet_ntoa(socket.addr.sin_addr);
00286 #endif
00287
00288 lastCode = socket.sock;
00289
00290 if ( socket.sock == SOCKET_ERROR )
00291 return false;
00292
00293 socket.state = skCONNECTED;
00294 return true;
00295 }
00296
00297 ezSockets * ezSockets::Accept()
00298 {
00299 if (!bBlocking && !CanRead())
00300 return NULL;
00301
00302 sockaddr_in local_addr;
00303 int length = sizeof(local_addr);
00304
00305 int localsock = ::accept(sock,(struct sockaddr*) &local_addr,
00306 (socklen_t*) &length);
00307
00308 if ( localsock == SOCKET_ERROR )
00309 return NULL;
00310
00311 ezSockets * sNew = new ezSockets;
00312
00313 #if !( defined (_WIN32) || defined( _XBOX ) )
00314 char buf[INET_ADDRSTRLEN];
00315 inet_ntop(AF_INET, &local_addr.sin_addr, buf, INET_ADDRSTRLEN);
00316 sNew->address = buf;
00317 #else
00318 sNew->address = inet_ntoa(local_addr.sin_addr);
00319 #endif
00320
00321 lastCode = localsock;
00322
00323
00324 sNew->bBlocking = bBlocking;
00325 sNew->lastCode = 0;
00326 sNew->mode = mode;
00327 sNew->pDataInHead = NULL;
00328 sNew->sock = localsock;
00329 sNew->state = skCONNECTED;
00330 return sNew;
00331 }
00332
00333 void ezSockets::Close()
00334 {
00335 state = skDISCONNECTED;
00336
00337 if ( pDataInHead )
00338 {
00339 pDataInHead->DestroyTree();
00340 delete pDataInHead;
00341 pDataInHead = NULL;
00342 }
00343
00344 #if defined(WIN32) // The close socket command is different in Windows
00345 ::closesocket(sock);
00346 #else
00347 ::close(sock);
00348 #endif
00349 }
00350
00351 bool ezSockets::Connect(const MString& host, unsigned short port)
00352 {
00353 if(!Check())
00354 return false;
00355
00356 #if defined(_XBOX)
00357 if(!isdigit(host[0]))
00358 {
00359 XNDNS *pxndns = NULL;
00360 XNetDnsLookup(host.c_str(), NULL, &pxndns);
00361 while (pxndns->iStatus == WSAEINPROGRESS)
00362 {
00363
00364 }
00365
00366 if (pxndns->iStatus == 0)
00367 memcpy(&addr.sin_addr, &pxndns->aina[0], sizeof(struct in_addr));
00368 else
00369 return false;
00370
00371 XNetDnsRelease(pxndns);
00372 }
00373 else
00374 addr.sin_addr.s_addr = inet_addr(host.c_str());
00375 #else
00376 struct hostent* phe;
00377 phe = gethostbyname(host.c_str());
00378 if (phe == NULL)
00379 return false;
00380 memcpy(&addr.sin_addr, phe->h_addr, sizeof(struct in_addr));
00381 #endif
00382 addr.sin_family = AF_INET;
00383 addr.sin_port = htons(port);
00384
00385 if(::connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
00386 return false;
00387
00388 state = skCONNECTED;
00389 return true;
00390 }
00391
00392 bool ezSockets::CanRead()
00393 {
00394 FD_ZERO(scks);
00395 FD_SET((unsigned)sock, scks);
00396
00397 return select(sock+1,scks,NULL,NULL,times) > 0;
00398 }
00399
00400 bool ezSockets::DataAvailable()
00401 {
00402 if ( CanRead() )
00403 return true;
00404
00405
00406 if ( pDataInHead )
00407 if ( pDataInHead->PositionTAG != pDataInHead->Position )
00408 return true;
00409 return false;
00410 }
00411
00412 bool ezSockets::IsError()
00413 {
00414 if (state == skERROR)
00415 return true;
00416
00417 FD_ZERO(scks);
00418 FD_SET((unsigned)sock, scks);
00419
00420 if (select(sock+1, NULL, NULL, scks, times) >=0 )
00421 return false;
00422
00423 state = skERROR;
00424 return true;
00425 }
00426
00427 bool ezSockets::CanWrite()
00428 {
00429 FD_ZERO(scks);
00430 FD_SET((unsigned)sock, scks);
00431
00432 return select(sock+1, NULL, scks, NULL, times) > 0;
00433 }
00434
00435
00436 void ezSockets::SendData(const MString& outData)
00437 {
00438 if ( mode == skGeneral )
00439 pWriteData( outData.c_str(), outData.length() );
00440 }
00441
00442 void ezSockets::SendData(const char *data, unsigned int bytes)
00443 {
00444 if ( mode == skGeneral )
00445 pWriteData( data, bytes );
00446 }
00447
00448 int ezSockets::ReadData(char *data, unsigned int bytes)
00449 {
00450 if ( mode != skGeneral )
00451 return -1;
00452 int iRL = ReadLeftover( data, bytes );
00453 while ( iRL < (int)bytes )
00454 {
00455 int iGot = pReadData( data + iRL, ((int)bytes) - iRL );
00456 if ( iGot <= 0 )
00457 return iRL;
00458 iRL += iGot;
00459 }
00460 return iRL;
00461 }
00462
00463 int ezSockets::PeekData(char *data, unsigned int bytes)
00464 {
00465 if ( mode != skGeneral )
00466 return -1;
00467
00468 int iRL = 0;
00469 ReceiveGeneralData();
00470 ezSocketsPacket * tmp = pDataInHead;
00471
00472 while ( tmp )
00473 {
00474 int iPotential = tmp->Size - tmp->Position;
00475 if ( iPotential > ((int)bytes)-iRL )
00476 iPotential = bytes-iRL;
00477 memcpy( data + iRL, tmp->Data + tmp->Position, iPotential );
00478 iRL += iPotential;
00479 if ( iRL >= ((int)bytes) )
00480 return iRL;
00481 tmp = tmp->Next;
00482 }
00483 return iRL;
00484 }
00485
00486
00487 bool ezSockets::ReadLine( MString & str )
00488 {
00489 if ( mode != skGeneral )
00490 return false;
00491
00492 str = "";
00493 ReceiveGeneralData();
00494
00495 ezSocketsPacket * tmp = pDataInHead;
00496
00497 bool bFound = false;
00498 unsigned int i = 0;
00499
00500 while ( tmp )
00501 {
00502 for ( i = tmp->Position; i < tmp->PositionTAG; i++ )
00503 if ( tmp->Data[i] == '\n' )
00504 {
00505 bFound = true;
00506 break;
00507 }
00508 if ( !bFound )
00509 tmp = tmp->Next;
00510 else
00511 break;
00512 }
00513
00514 if ( !bFound && !bBlocking )
00515 return false;
00516
00517 if ( bFound )
00518 while ( pDataInHead != tmp )
00519 {
00520 str.append( pDataInHead->Data, pDataInHead->Size-pDataInHead->Position );
00521 pDataInHead = pDataInHead->Next;
00522 }
00523
00524 if ( pDataInHead )
00525 if ( i != pDataInHead->Position )
00526 {
00527 str.append( pDataInHead->Data + pDataInHead->Position, i - pDataInHead->Position );
00528 pDataInHead->Position = i + 1;
00529 }
00530
00531
00532 if ( !bFound && bBlocking )
00533 {
00534 if ( pDataInHead )
00535 pDataInHead->Position = pDataInHead->PositionTAG;
00536
00537 char tmp = '\0';
00538 while ( tmp != '\n' )
00539 {
00540 if ( ReadLeftover( &tmp, 1 ) != 1 )
00541 return false;
00542 if ( tmp != '\n' )
00543 str.append( &tmp, 1 );
00544 }
00545 }
00546
00547 if ( str.length() > 0 )
00548 if ( str.c_str()[str.length()-1] == '\r' )
00549 str.resize ( str.length() - 1 );
00550
00551 return true;
00552 }
00553
00554 void ezSockets::WriteLine( const MString & str )
00555 {
00556 SendData( str.c_str(), str.length() );
00557 SendData( "\r\n", 2 );
00558 }
00559
00560 int ezSockets::ReadLeftover( char * data, unsigned int maxbytes )
00561 {
00562 if ( mode != skGeneral )
00563 return -1;
00564
00565 ReceiveGeneralData();
00566
00567 int iPos = 0;
00568
00569 while ( pDataInHead )
00570 {
00571 int iMemToRead = pDataInHead->PositionTAG - pDataInHead->Position;
00572 if ( iMemToRead == 0 )
00573 break;
00574 if ( iMemToRead > ( ((int)maxbytes) - iPos ) )
00575 iMemToRead = maxbytes - iPos;
00576
00577 memcpy( data + iPos, pDataInHead->Data + pDataInHead->Position, iMemToRead );
00578
00579 pDataInHead->Position += iMemToRead;
00580 iPos += iMemToRead;
00581
00582 if ( pDataInHead->Position == pDataInHead->Size )
00583 {
00584 if ( pDataInHead == pDataInTail )
00585 {
00586 delete pDataInHead;
00587 pDataInHead = 0;
00588 pDataInTail = 0;
00589 return iPos;
00590 } else {
00591 ezSocketsPacket * tmp = pDataInHead;
00592 pDataInHead = pDataInHead->Next;
00593 delete tmp;
00594 }
00595 }
00596
00597 if ( iPos >= ((int)maxbytes) )
00598 return iPos;
00599 }
00600
00601 if ( bBlocking )
00602 {
00603 int iRead = pReadData( Buffer, (ezSocketsBuffersize<maxbytes)?ezSocketsBuffersize:maxbytes );
00604 if ( iRead > 0 )
00605 {
00606 memcpy( data+iPos, Buffer, iRead );
00607 return iRead+iPos;
00608 }
00609 else
00610 return iPos;
00611 } else
00612 return iPos;
00613 }
00614
00615 void ezSockets::ReceiveGeneralData( bool bForceBlock )
00616 {
00617 if ( mode == skGeneral )
00618 {
00619 while( CanRead() )
00620 {
00621 if( pDataInTail )
00622 {
00623 if ( pDataInTail->Size <= pDataInTail->PositionTAG )
00624 {
00625 pDataInTail->Next = new ezSocketsPacket;
00626 pDataInTail = pDataInTail->Next;
00627 pDataInTail->Next = NULL;
00628 pDataInTail->SetupPacket( ezSocketsBuffersize );
00629 pDataInTail->PositionTAG = 0;
00630 } else {
00631 int rec = pReadData( pDataInTail->Data + pDataInTail->PositionTAG, pDataInTail->Size - pDataInTail->PositionTAG );
00632 if ( rec>0 )
00633 pDataInTail->PositionTAG += rec;
00634 else
00635 break;
00636 }
00637 }
00638 else
00639 {
00640 pDataInTail = new ezSocketsPacket;
00641 pDataInHead = pDataInTail;
00642 pDataInHead->SetupPacket( ezSocketsBuffersize );
00643 pDataInHead->PositionTAG = 0;
00644 }
00645 }
00646 return;
00647 } else if ( mode == skPackets )
00648 {
00649 bool bGotPack = false;
00650 if ( pDataInTail )
00651 if ( pDataInTail->PositionTAG >= 4 && pDataInTail->Position == pDataInTail->Size )
00652 bGotPack = true;
00653 while ( CanRead() || ( bForceBlock && !bGotPack ) )
00654 {
00655 if ( !pDataInTail )
00656 {
00657 pDataInHead = new ezSocketsPacket;
00658 pDataInTail = pDataInHead;
00659 pDataInTail->Next = NULL;
00660 pDataInTail->PositionTAG = 0;
00661 }
00662 if ( pDataInTail->PositionTAG == 4 && pDataInTail->Size == pDataInTail->Position )
00663 {
00664 pDataInTail->Next = new ezSocketsPacket;
00665 pDataInTail = pDataInTail->Next;
00666 pDataInTail->Next = NULL;
00667 pDataInTail->PositionTAG = 0;
00668 }
00669 if ( pDataInTail->PositionTAG < 4 )
00670 {
00671 int recv = pReadData( Buffer, 4 - pDataInTail->PositionTAG );
00672 int cpos = 0;
00673 unsigned int oldpos = pDataInTail->PositionTAG;
00674 pDataInTail->PositionTAG+=recv;
00675 if ( recv > 0 )
00676 {
00677 for ( ; oldpos < pDataInTail->PositionTAG; oldpos++ )
00678 {
00679 unsigned long j = (unsigned char)Buffer[cpos];
00680 pDataInTail->Size += j<<(8*(3-oldpos));
00681 cpos++;
00682 }
00683 } else
00684 return;
00685 if ( pDataInTail->PositionTAG == 4 )
00686 {
00687 pDataInTail->SetupPacket( pDataInTail->Size );
00688 pDataInTail->Position = 0;
00689 }
00690 } else
00691 {
00692 int recv = pReadData( pDataInTail->Data + pDataInTail->Position, pDataInTail->Size - pDataInTail->Position );
00693 if ( recv > 0 )
00694 pDataInTail->Position += recv;
00695 else
00696 return;
00697 }
00698
00699 if ( pDataInTail )
00700 if ( pDataInTail->PositionTAG >= 4 && pDataInTail->Position == pDataInTail->Size )
00701 bGotPack = true;
00702 }
00703 } else if ( mode == skUDP )
00704 {
00705 if ( CanRead() || bForceBlock )
00706 {
00707 int j = fromAddr.sin_addr.s_addr;
00708 int iRead = pReadData( Buffer, ezSocketsBuffersize );
00709 int pAddy = ntohl(fromAddr.sin_addr.s_addr);
00710 int pPort = ntohs(fromAddr.sin_port);
00711
00712 if ( iRead>0 )
00713 {
00714 if ( !pDataInTail )
00715 {
00716 pDataInHead = new ezSocketsPacket;
00717 pDataInTail = pDataInHead;
00718 pDataInTail->PositionTAG = 0;
00719 } else {
00720 ezSocketsPacket * tmp = pDataInTail;
00721 pDataInTail = new ezSocketsPacket;
00722 tmp->Next = pDataInTail;
00723 }
00724
00725 pDataInTail->SetupPacket( iRead );
00726 memcpy( pDataInTail->Data, Buffer, iRead );
00727 pDataInTail->PositionTAG = pAddy;
00728 pDataInTail->Port = pPort;
00729 }
00730 }
00731 }
00732 }
00733
00734 void ezSockets::SendPack( const ezSocketsPacket &pPack )
00735 {
00736
00737
00738
00739
00740 char * sToSend = (char*)malloc( pPack.Size + 4 );
00741 unsigned int nBytes = htonl( pPack.Size );
00742 memcpy( sToSend, &nBytes, 4 );
00743 memcpy( sToSend + 4, pPack.Data, pPack.Size );
00744 if( pPack.Port != 0 && mode == skUDP )
00745 {
00746 sockaddr_in to;
00747 to.sin_port = htons( pPack.Port );
00748 to.sin_family = AF_INET;
00749 to.sin_addr.s_addr = htonl( pPack.PositionTAG );
00750 memset( to.sin_zero, 0, 8 );
00751 bool j = (sendto( sock, sToSend, pPack.Size + 4 , 0, (sockaddr*)&to, sizeof( sockaddr_in ) )!=0);
00752 }
00753 else
00754 pWriteData( sToSend, pPack.Size + 4 );
00755 free( sToSend );
00756 }
00757
00758 int ezSockets::ReadPack( ezSocketsPacket &pPack )
00759 {
00760 ReceiveGeneralData();
00761 if( pDataInHead )
00762 {
00763 if ( ( pDataInHead->Position == pDataInHead->Size || mode == skUDP ) && pDataInHead->PositionTAG >= 4 )
00764 {
00765
00766 pPack.~ezSocketsPacket();
00767 pPack = (*pDataInHead);
00768
00769 ezSocketsPacket * g = pDataInHead;
00770
00771 pPack.Position = 0;
00772
00773 if ( pDataInHead == pDataInTail )
00774 {
00775 pDataInHead = NULL;
00776 pDataInTail = NULL;
00777 } else
00778 pDataInHead = pDataInHead->Next;
00779
00780 free( g );
00781
00782 return 1;
00783 }
00784 }
00785
00786 if ( bBlocking )
00787 {
00788 ReceiveGeneralData( true );
00789 if( pDataInHead )
00790 {
00791 if ( ( pDataInHead->Position == pDataInHead->Size || mode == skUDP ) && pDataInHead->PositionTAG >= 4 )
00792 {
00793
00794 pPack.~ezSocketsPacket();
00795 pPack = (*pDataInHead);
00796
00797 ezSocketsPacket * g = pDataInHead;
00798 pPack.Position = 0;
00799
00800 if ( pDataInHead == pDataInTail )
00801 {
00802 pDataInHead = NULL;
00803 pDataInTail = NULL;
00804 } else
00805 pDataInHead = pDataInHead->Next;
00806
00807 free( g );
00808
00809 return 1;
00810 }
00811 }
00812 }
00813
00814 return 0;
00815 }
00816
00817 int ezSockets::PeekPack( ezSocketsPacket &pPack )
00818 {
00819 ReceiveGeneralData();
00820 if( pDataInHead )
00821 {
00822 if ( pDataInHead->Position == pDataInHead->Size )
00823 {
00824 pPack.CopyPacket( *pDataInHead );
00825 pPack.Position = 0;
00826 return 1;
00827 }
00828 }
00829 return 0;
00830 }
00831
00832
00833 bool ezSockets::SetupForReuseAddr( bool bAllow )
00834 {
00835 #ifdef SO_REUSEADDR
00836
00837 char optval = (bAllow)?1:0;
00838 return setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval) ) >= 0;
00839 #else
00840 return false;
00841 #endif
00842 }
00843
00844 bool ezSockets::SetupForMulticast( const MString & sAddressToJoin )
00845 {
00846 #ifdef IP_ADD_MEMBERSHIP
00847 ip_mreq jgrp;
00848 jgrp.imr_multiaddr.s_addr = inet_addr( sAddressToJoin.c_str() );
00849 jgrp.imr_interface.s_addr = htonl( INADDR_ANY );
00850 return setsockopt( sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &jgrp, sizeof(jgrp) ) >= 0;
00851 #else
00852 return false;
00853 #endif
00854 }
00855
00856 bool ezSockets::SetupForBroadcast( bool bBroadcast )
00857 {
00858 #ifdef SO_BROADCAST
00859 char optval = (bBroadcast)?1:0;
00860 return setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof( optval ) ) >= 0;
00861 #else
00862 return false;
00863 #endif
00864 }
00865
00866 int ezSockets::pReadData(char* data, int maxsize )
00867 {
00868 if(state == skCONNECTED || state == skLISTENING)
00869 return recv(sock, data, maxsize, 0);
00870
00871 int saddrinlen = sizeof(sockaddr_in);
00872
00873 return recvfrom(sock, data, maxsize, 0, (sockaddr*)&fromAddr,
00874 (socklen_t*)&saddrinlen);
00875 }
00876
00877 int ezSockets::pWriteData(const char* data, int dataSize)
00878 {
00879 #if defined(WIN32)
00880 return send(sock, data, dataSize, 0);
00881 #else
00882 return send(sock, data, dataSize, MSG_NOSIGNAL);
00883 #endif
00884 }
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909