D:/Zythum/DinoKod/Network/Socket.cpp

00001 //---------------------------------------------------------------------------------------------
00002 //      This file is a part of "DinoKod".
00003 //      Copyright © 2003 Dino Productions. All Rights Reserved.
00004 //      
00005 //      File                    : Socket.cpp
00006 //      Author                  : Sebastien LEIX        sebastien.leix@wanadoo.fr
00007 //      Date                    : 09/09/2002
00008 //      Modification    :
00009 //
00010 //---------------------------------------------------------------------------------------------
00011 #include "Common/Error.h"
00012 #include "Common/Console.h"
00013 #include "Common/Lzw.h"
00014 #include "Network/InetAddr.h"
00015 #include "Network/Socket.h"
00016 
00017 //---------------------------------------------------------------------------------------------------------------------
00018 //---------------------------------------------------------------------------------------------------------------------
00019 //---------------------------------------------------------------------------------------------------------------------
00020 KSocket::KSocket()
00021 {
00022         m_hSocket                       = INVALID_SOCKET;
00023         m_bConnected            = false;
00024         m_nBytesSent            = 0;
00025         m_nBytesReceived        = 0;
00026         m_nRealBytesSent        = 0;
00027         m_nRealBytesReceived= 0;
00028         m_bCompress                     = false;
00029         m_bAttached                     = false;
00030 }
00031 
00032 //---------------------------------------------------------------------------------------------------------------------
00033 KSocket::~KSocket()
00034 {
00035         if( m_hSocket != INVALID_SOCKET )
00036         {
00037                 Close();
00038         }
00039 }
00040 
00041 //---------------------------------------------------------------------------------------------------------------------
00042 bool KSocket::Create( KNSOCKETTYPE Type )
00043 {
00044         switch( Type )
00045         {
00046         case KNST_TCP:
00047                 m_hSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
00048                 break;
00049         case KNST_UDP:
00050                 m_hSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
00051                 break;
00052         default:
00053                 KError::FatalError( NULL, " KSocket::Create(...) : Unknown socket type %i", Type );
00054                 return false;
00055         }
00056 
00057         if( m_hSocket == INVALID_SOCKET )
00058         {
00059                 KError::FatalError( NULL, GetLastError(), "KSocket::Create(...) : Cannot create socket"  );
00060                 return false;
00061         }
00062 
00063         return true;
00064 }
00065 
00066 //---------------------------------------------------------------------------------------------------------------------
00067 bool KSocket::Close()
00068 {
00069         if( !m_bAttached )
00070         {
00071                 if( closesocket( m_hSocket ) == SOCKET_ERROR )
00072                 {
00073                         KError::FatalError( NULL, GetLastError(), "KSocket::Close(...) : Cannot close socket"  );
00074                         return false;
00075                 }
00076         }
00077 
00078         Detach();
00079 
00080         return true;
00081 }
00082 
00083 //---------------------------------------------------------------------------------------------------------------------
00084 bool KSocket::Attach( SOCKET hSocket )
00085 {
00086         if( m_hSocket != INVALID_SOCKET )
00087         {
00088                 KError::FatalError( NULL, GetLastError(), "KSocket::Attach(...) : Socket already attached"  );
00089                 return false;
00090         }
00091 
00092         m_hSocket = hSocket;
00093 
00094         m_bAttached = true;
00095 
00096         return true;
00097 }
00098 
00099 //---------------------------------------------------------------------------------------------------------------------
00100 bool KSocket::Detach()
00101 {
00102         if( m_hSocket == INVALID_SOCKET )
00103         {
00104                 KError::FatalError( NULL, GetLastError(), "KSocket::Detach(...) : Socket already detached"  );
00105                 return false;
00106         }
00107 
00108         m_hSocket = INVALID_SOCKET;
00109 
00110         m_bAttached = false;
00111 
00112         return true;
00113 }
00114 
00115 //---------------------------------------------------------------------------------------------------------------------
00116 bool KSocket::Bind( KInetAddr& Addr )
00117 {
00118         sockaddr_in     in;
00119         
00120         in.sin_port             = htons(Addr.GetPort());
00121         in.sin_addr             = Addr.GetInAddr();
00122         in.sin_family   = AF_INET;
00123 
00124         if( bind( m_hSocket, (const sockaddr*)&in, sizeof( in ) ) == SOCKET_ERROR )
00125         {
00126                 KError::FatalError( NULL, GetLastError(), "KSocket::Bind() : bind failed"  );
00127                 return false;
00128         }
00129 
00130         return true;
00131 }
00132 
00133 //---------------------------------------------------------------------------------------------------------------------
00134 bool KSocket::SelectRead()
00135 {
00136         fd_set  fdset;
00137         
00138         FD_ZERO( &fdset );
00139         FD_SET( m_hSocket, &fdset );
00140         
00141         timeval tv;
00142         tv.tv_sec       = 0;
00143         tv.tv_usec      = 0;
00144 
00145         // Test for message received.
00146         int res = select( (int)m_hSocket + 1, &fdset, NULL, NULL, &tv );
00147         switch ( res  )
00148         {
00149                 case  0:
00150                         return false;
00151                 case -1:
00152                         KError::FatalError( NULL, GetLastError(), "KSocket::SelectRead(...) : select failed"  );
00153                         return false;
00154         }
00155 
00156         return true;
00157 }
00158 
00159 //---------------------------------------------------------------------------------------------------------------------
00160 bool KSocket::SelectWrite()
00161 {
00162         fd_set  fdset;
00163         
00164         FD_ZERO( &fdset );
00165         FD_SET( m_hSocket, &fdset );
00166         
00167         timeval tv;
00168         tv.tv_sec       = 0;
00169         tv.tv_usec      = 0;
00170 
00171         // Test for message received.
00172         int res = select( (int)m_hSocket + 1, NULL, &fdset, NULL, &tv );
00173         switch ( res  )
00174         {
00175                 case  0:
00176                         return false;
00177                 case -1:
00178                         KError::FatalError( NULL, GetLastError(), "KSocket::SelectWrite(...) : select failed"  );
00179                         return false;
00180         }
00181 
00182         return true;
00183 }
00184 
00185 //---------------------------------------------------------------------------------------------------------------------
00186 bool KSocket::SelectExcept()
00187 {
00188         fd_set  fdset;
00189         
00190         FD_ZERO( &fdset );
00191         FD_SET( m_hSocket, &fdset );
00192         
00193         timeval tv;
00194         tv.tv_sec       = 0;
00195         tv.tv_usec      = 0;
00196 
00197         // Test for message received.
00198         int res = select( (int)m_hSocket + 1, NULL, NULL, &fdset, &tv );
00199         switch ( res  )
00200         {
00201                 case  0:
00202                         return false;
00203                 case -1:
00204                         KError::FatalError( NULL, GetLastError(), "KSocket::SelectExcept(...) : select failed"  );
00205                         return false;
00206         }
00207 
00208         return true;
00209 }
00210 
00211 //---------------------------------------------------------------------------------------------------------------------
00212 bool KSocket::Connect( KInetAddr& Addr )
00213 {
00214         sockaddr_in     in;
00215         
00216         in.sin_port             = htons(Addr.GetPort());
00217         in.sin_addr             = Addr.GetInAddr();
00218         in.sin_family   = AF_INET;
00219 
00220         if( connect( m_hSocket, (const sockaddr*)&in, sizeof( in ) ) == SOCKET_ERROR )
00221         {
00222                 KError::FatalError( NULL, GetLastError(), "KSocket::Connect() : connect failed"  );
00223                 return false;
00224         }
00225 
00226         m_bConnected = true;
00227 
00228         return true;
00229 }
00230 
00231 //---------------------------------------------------------------------------------------------------------------------
00232 bool KSocket::Disconnect()
00233 {
00234         if( shutdown( m_hSocket, 2 ) == SOCKET_ERROR )
00235         {
00236                 KError::FatalError( NULL, GetLastError(), "KSocket::Disconnect() : shutdown failed"  );
00237                 return false;
00238         }
00239 
00240         m_bConnected = false;
00241 
00242         return true;
00243 }
00244 
00245 //---------------------------------------------------------------------------------------------------------------------
00246 bool KSocket::Listen()
00247 {
00248         if( listen( m_hSocket, SOMAXCONN ) == SOCKET_ERROR )
00249         {
00250                 KError::FatalError( NULL, GetLastError(), "KSocket::Listen() : listen failed"  );
00251                 return false;
00252         }
00253         return true;
00254 }
00255 
00256 //---------------------------------------------------------------------------------------------------------------------
00257 bool KSocket::Accept( KSocket& AcceptedSocket, KInetAddr& Addr )
00258 {
00259         sockaddr_in     in;
00260         SOCKET          hSocket;
00261         
00262         in.sin_port             = htons(Addr.GetPort());
00263         in.sin_addr             = Addr.GetInAddr();
00264         in.sin_family   = AF_INET;
00265 
00266         s32             Length = sizeof( in );
00267         
00268         if( ( hSocket = accept( m_hSocket, (sockaddr*)&in, (int*)&Length ) ) == SOCKET_ERROR )
00269         {
00270                 KError::FatalError( NULL, GetLastError(), "KSocket::Accept() : accept failed"  );
00271                 return false;
00272         }
00273         
00274         AcceptedSocket.Attach( hSocket );
00275         AcceptedSocket.SetConnected( true );
00276 
00277         return true;
00278 }
00279 
00280 //---------------------------------------------------------------------------------------------------------------------
00281 bool KSocket::Send( void* pBuffer, s32 Size )
00282 {
00283         s32     result;
00284         
00285         // Envoie le buffer
00286         result = send( m_hSocket, (char*)pBuffer, Size, 0 );
00287         if( result == SOCKET_ERROR )
00288         {
00289                 u32             Error = GetLastError();
00290                 
00291                 if( Error == WSAECONNRESET )
00292                 {
00293                         // Socket distante déconnectée
00294                         Disconnect();
00295                         OnClose();
00296                         return false;
00297                 }
00298                 
00299                 KError::FatalError( NULL, Error, "KSocket::Send() : send failed"  );
00300                 return false;
00301         }
00302 
00303         if( result != Size )
00304         {
00305                 KError::FatalError( NULL, GetLastError(), "KSocket::Send() : %i of %i bytes sent.", result, Size  );
00306                 return false;
00307         }
00308 
00309         m_nBytesSent            += Size;
00310         m_nRealBytesSent        += Size;
00311 
00312         return true;
00313 }
00314 
00315 //---------------------------------------------------------------------------------------------------------------------
00316 bool KSocket::Receive( void* pBuffer, s32 Size, u32* pBytesRead )
00317 {
00318         s32     Result;
00319         
00320         Result = recv( m_hSocket, (char*)pBuffer, Size, 0 );
00321         if( Result == SOCKET_ERROR )
00322         {
00323                 KError::FatalError( NULL, GetLastError(), "KSocket::Receive() : recv failed"  );
00324                 return false;
00325         }
00326 
00327         *pBytesRead = Result;
00328         m_nBytesReceived                += *pBytesRead;
00329         m_nRealBytesReceived    += *pBytesRead;
00330 
00331         return true;
00332 }
00333 
00334 //---------------------------------------------------------------------------------------------------------------------
00335 bool KSocket::SendTo( KInetAddr& Addr, void* pBuffer, u32 Size )
00336 {
00337         sockaddr_in     in;
00338         
00339         in.sin_port             = htons(Addr.GetPort());
00340         in.sin_addr             = Addr.GetInAddr();
00341         in.sin_family   = AF_INET;
00342 
00343         // Compresse les données si necessaire
00344         char*   pBufferToSend   = (char*)pBuffer;
00345         u32             SizeToSend              = Size;
00346         u8              pOut[1024];
00347         s32             OutSize = sizeof( pOut );
00348 
00349         if( m_bCompress )
00350         {
00351                 g_Lzw.Compress( (u8*)pBuffer, Size, pOut, &OutSize );
00352                 pBufferToSend   = (char*)pOut;
00353                 SizeToSend              = OutSize;
00354         }
00355 
00356 //      g_Console << "SendTo : " << Size << KENDL;
00357         // Envoie le packet
00358         if( sendto( m_hSocket, (char*)pBufferToSend, SizeToSend, 0, (const sockaddr*)&in, sizeof( in ) ) == SOCKET_ERROR )
00359         {
00360                 KError::FatalError( NULL, GetLastError(), "KSocket::SendTo() : sendto failed"  );
00361                 return false;
00362         }
00363 
00364         m_nBytesSent            += SizeToSend;
00365         m_nRealBytesSent        += Size;
00366 
00367         return true;
00368 }
00369 
00370 //---------------------------------------------------------------------------------------------------------------------
00371 bool KSocket::ReceiveFrom( KInetAddr& Addr, void* pBuffer, u32 Size, u32* pBytesRead )
00372 {
00373         sockaddr_in     in;
00374         s32                     InLenght = sizeof( in );
00375         s32                     Result;
00376         char            pBufferToReceive[1024];
00377         
00378         Result = recvfrom( m_hSocket, (char*)pBufferToReceive, sizeof( pBufferToReceive ), 0, (sockaddr*)&in, (int*)&InLenght );
00379         if( Result == SOCKET_ERROR )
00380         {
00381                 if( GetLastError() == WSAECONNRESET )
00382                         return false;
00383 
00384                 KError::FatalError( NULL, GetLastError(), "KSocket::ReceiveFrom() : receivefrom failed"  );
00385                 return false;
00386         }
00387 
00388         // Décompresse les données si necessaire
00389         u8              pOut[1024];
00390         s32             OutSize = Size;
00391 
00392         if( m_bCompress )
00393         {
00394                 g_Lzw.Expand( (u8*)pBufferToReceive, Result, pOut, &OutSize );
00395                 memcpy( pBuffer, pOut, OutSize);                
00396                 *pBytesRead = OutSize;
00397         }
00398         else
00399         {
00400                 memcpy( pBuffer, pBufferToReceive, Result );
00401                 *pBytesRead = Result;
00402         }
00403 
00404         Addr.SetInAddr( in.sin_addr );
00405         Addr.SetPort( ntohs(in.sin_port) );
00406 
00407         m_nBytesReceived                += Result;
00408         m_nRealBytesReceived    += *pBytesRead;
00409 
00410 //      g_Console << "Received : " << *pBytesRead << KENDL;
00411 
00412         return true;
00413 }
00414 
00415 //---------------------------------------------------------------------------------------------------------------------
00416 bool KSocket::AsyncSelect()
00417 {
00418         fd_set  ReadFds;
00419         fd_set  WriteFds;
00420         fd_set  ExceptFds;
00421         
00422         FD_ZERO( &ReadFds );
00423         FD_ZERO( &WriteFds );
00424         FD_ZERO( &ExceptFds );
00425         FD_SET( m_hSocket, &ReadFds );
00426         FD_SET( m_hSocket, &WriteFds );
00427         FD_SET( m_hSocket, &ExceptFds );
00428         
00429         timeval tv;
00430         tv.tv_sec       = 0;
00431         tv.tv_usec      = 0;
00432 
00433         int res = select( (int)m_hSocket + 1, &ReadFds, &WriteFds, &ExceptFds, &tv );
00434         switch ( res  )
00435         {
00436                 case  0:
00437                         return false;
00438                 case -1:
00439                         KError::FatalError( NULL, GetLastError(), "KSocket::AsyncSelect(...) : select failed"  );
00440                         return false;
00441         }
00442 
00443         KError::Warning( NULL, "KSocket::AsyncSelect()" );
00444 
00445         // Read
00446         if( FD_ISSET( m_hSocket, &ReadFds ) )
00447         {
00448                 BOOL    bAccept = false;
00449                 int             Size;
00450 
00451                 Size = sizeof( bAccept );
00452                 getsockopt( m_hSocket, SOL_SOCKET, SO_ACCEPTCONN, (char*)&bAccept, &Size );
00453 
00454                 if( bAccept )
00455                 {
00456                         // SERVEUR
00457                         OnAccept();
00458                 }
00459                 else
00460                 {
00461                         // CLIENT
00462                         int             Result;
00463                         char    Data;
00464 
00465                         // Si result == 0, c est un evenement Close sinon c'est un Read
00466                         Result = recv( m_hSocket, &Data, 1, MSG_PEEK );
00467                         if( ( Result == SOCKET_ERROR ) && ( GetLastError() != WSAEMSGSIZE ) )
00468                         {
00469                                 KError::FatalError( NULL, GetLastError(), "KSocket::AsyncSelect(...) : recv failed"  );
00470                                 return false;
00471                         }
00472 
00473                         if( !Result )
00474                         {
00475                                 OnClose();
00476                                 Disconnect();
00477                         }
00478                         else
00479                                 OnRead();
00480                 }
00481         }
00482         // Write
00483         if( FD_ISSET( m_hSocket, &WriteFds ) )
00484         {
00485                 OnWrite();
00486         }
00487         // Except
00488         if( FD_ISSET( m_hSocket, &ExceptFds ) )
00489         {
00490                 OnOOB();
00491         }
00492 
00493         return true;
00494 }
00495 
00496 //---------------------------------------------------------------------------------------------------------------------
00497 void KSocket::OnAccept()
00498 {
00499         KError::Warning( NULL, "KSocket::OnAccept()" );
00500 /*
00501         static KSocket          Socket;
00502         KInetAddr       Addr;
00503         Accept( Socket, Addr );
00504         while( Socket.IsConnected() )
00505         {
00506                 Socket.AsyncSelect();
00507         }*/
00508 }
00509 
00510 //---------------------------------------------------------------------------------------------------------------------
00511 void KSocket::OnRead()
00512 {
00513 /*      char    pBuffer[1024];
00514         Receive( pBuffer, 1024 );*/
00515         KError::Warning( NULL, "KSocket::OnRead()" );
00516 }
00517 
00518 //---------------------------------------------------------------------------------------------------------------------
00519 void KSocket::OnWrite()
00520 {
00521         KError::Warning( NULL, "KSocket::OnWrite()" );
00522 }
00523 
00524 //---------------------------------------------------------------------------------------------------------------------
00525 void KSocket::OnClose()
00526 {
00527         KError::Warning( NULL, "KSocket::OnClose()" );
00528 }
00529 
00530 //---------------------------------------------------------------------------------------------------------------------
00531 void KSocket::OnOOB()
00532 {
00533         KError::Warning( NULL, "KSocket::OnOOB()" );
00534 }
00535 
00536 //---------------------------------------------------------------------------------------------------------------------
00537 //---------------------------------------------------------------------------------------------------------------------
00538 bool KSocket::StartNetwork()
00539 {
00540         WORD    Version = MAKEWORD( 2, 2 ); 
00541         WSADATA wsaData;
00542         
00543         if( WSAStartup( Version, &wsaData ) != 0 )
00544         {
00545                 KError::FatalError( NULL, GetLastError(), "KSocket::StartNetwork() : Cannot start network"  );
00546                 return false;
00547         }
00548 
00549 //      g_Console << "Winsock v" << LOBYTE( wsaData.wVersion ) << "." << HIBYTE( wsaData.wVersion ) << KENDL;
00550         
00551         return true;
00552 }
00553 
00554 //---------------------------------------------------------------------------------------------------------------------
00555 bool KSocket::StopNetwork()
00556 {
00557         if( WSACleanup() == SOCKET_ERROR )
00558         {
00559                 KError::FatalError( NULL, GetLastError(), "KSocket::StopNetwork() : Cannot stop network"  );
00560                 return false;
00561         }
00562         return true;
00563 }
00564 
00565 //---------------------------------------------------------------------------------------------------------------------
00566 bool KSocket::GetHostName( char* pBuffer, s32 Size )
00567 {
00568         if( gethostname( pBuffer, Size ) == SOCKET_ERROR )
00569         {
00570                 KError::FatalError( NULL, GetLastError(), "KSocket::GetHostName() : gethostname failed"  );
00571                 return false;
00572         }
00573         return true;
00574 }
00575 
00576 //---------------------------------------------------------------------------------------------------------------------
00577 hostent* KSocket::GetHostByName( char* pName )
00578 {
00579         return gethostbyname( pName );
00580 }
00581 
00582 //---------------------------------------------------------------------------------------------------------------------
00583 hostent* KSocket::GetHostByAddr( KInetAddr& Addr )
00584 {
00585         char*   pAddr = Addr.GetpAddress();
00586         in_addr in;
00587 
00588         in.S_un.S_addr = inet_addr( pAddr );
00589         
00590         return gethostbyaddr( (char*)&in, (int)sizeof( in ), AF_INET );
00591 }
00592 
00593 //---------------------------------------------------------------------------------------------------------------------
00594 bool KSocket::GetAddrByName( KStr& sHostName, KInetAddr& Addr )
00595 {
00596         // Recupere l'IP de l'host
00597         HOSTENT*        pHostent;
00598 
00599         pHostent = KSocket::GetHostByName( sHostName );
00600         if( !pHostent || !pHostent->h_addr_list[0] )
00601                 return false;
00602         
00603         Addr.SetAddress( *((u32*)(pHostent->h_addr_list[0])) );
00604 
00605         return true;
00606 }
00607 
00608 //---------------------------------------------------------------------------------------------------------------------
00609 void KSocket::EnableBroadcast( bool bEnable )
00610 {
00611         setsockopt( m_hSocket, SOL_SOCKET, SO_BROADCAST, (char*)&bEnable, sizeof( bEnable ) );
00612 }
00613 

Generated on Sun Mar 25 20:02:15 2007 for Zythum Project by  doxygen 1.5.1-p1