void BTClient::Attach(SOCKET hSocket) { // IF the socket is already connected, kill the connection if( IsSocket() ) OnClose( 0 ); // clear all of the variables before the new connection Init(); // bind the socket and set the events m_hSocket = hSocket; EventSelect(FD_ALL_EVENTS); // get the new ip/port information sockaddr_in sinRemote; memset(&sinRemote,0,sizeof(sinRemote)); int nAddrSize=sizeof(sinRemote); getpeername( hSocket, (sockaddr *)&sinRemote, &nAddrSize ); // copy the ip/port information to the variables for quick lookup m_clientIP.SetIP( sinRemote.sin_addr.S_un.S_addr ); m_clientIP.SetPort( sinRemote.sin_port ); ::PostMessage( m_pParent->m_dlg_hwnd, WM_CMOD_SOCKET_CONNECT, (WPARAM)new IPPort(m_clientIP), NULL ); }
int WEventSocket::Create(unsigned short int port,unsigned int ip) { int ret=WSocket::Create(port); if((ret!=INVALID_SOCKET)&&(ret!=SOCKET_ERROR)) { // Do the event select crap ret=EventSelect(FD_ALL_EVENTS); } return ret; }
int CIpSocket::Create( int x_af, int x_type, int x_protocol, int x_timeout ) { // Punt if not initialized if ( !IsInitialized() ) return 0; // Close any open socket Destroy(); // Clear errors m_uLastError = 0; // Create a scocket m_hSocket = (t_SOCKET)socket( (int)x_af, (int)x_type, (int)x_protocol ); // Save the last error code m_uLastError = WSAGetLastError(); if ( WSAEWOULDBLOCK == m_uLastError ) m_uLastError = 0; // Was there an error? if ( c_InvalidSocket == m_hSocket ) { m_uConnectState |= eCsError; return 0; } // end if // Set default timeout if ( 0 >= x_timeout ) x_timeout = m_lTimeout; // Setup socket timeout defaults struct timeval tv; tv.tv_sec = ( x_timeout / 1000 ); tv.tv_usec = ( x_timeout % 1000 ) * 1000; setsockopt( (SOCKET)m_hSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof( tv ) ); setsockopt( (SOCKET)m_hSocket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof( tv ) ); // Process socket creation if ( !OnAttach() ) { Destroy(); return 0; } // end if // Save socket connect params m_uSocketFamily = x_af; m_uSocketType = x_type; m_uSocketProtocol = x_protocol; // Capture all events EventSelect(); return IsSocket(); }
int CIpSocket::Create( int x_af, int x_type, int x_protocol, int x_timeout ) { // Punt if not initialized if ( !IsInitialized() ) return 0; // Close any open socket Destroy(); // Create a scocket m_hSocket = (t_SOCKET)tcULongToPtr( socket( (int)x_af, (int)x_type, (int)x_protocol ) ); if ( c_InvalidSocket == m_hSocket ) { m_uLastError = errno; return 0; } // end if // Default timeout? if ( 0 >= x_timeout ) x_timeout = m_lTimeout; // Setup socket timeout defaults struct timeval tv; tv.tv_sec = ( x_timeout / 1000 ); tv.tv_usec = ( x_timeout % 1000 ) * 1000; setsockopt( tcPtrToULong( m_hSocket ), SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof( tv ) ); setsockopt( tcPtrToULong( m_hSocket ), SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof( tv ) ); // Process socket creation if ( !OnAttach() ) { Destroy(); return 0; } // end if m_uLastError = 0; // Save socket connect params m_uSocketFamily = x_af; m_uSocketType = x_type; m_uSocketProtocol = x_protocol; int set = 1; if ( -1 == setsockopt( tcPtrToULong( m_hSocket ), SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set) ) ) // WARNING( errno, tcT( "socket interface does not support SO_REUSEADDR" ) ); ; // Capture all events EventSelect(); return IsSocket(); }
BOOL CWinSocket::Create( int af, int type, int protocol ) {_STT(); // Punt if not initialized if ( !IsInitialized() ) { TRACE( "CWinSocket: Error - Call InitSockets()" ); return FALSE; } // Close any open socket Destroy(); // Create a scocket m_hSocket = socket( af, type, protocol ); // Save the last error code m_uLastError = WSAGetLastError(); // Create the event handle CreateEventHandle(); // Capture all events EventSelect(); return IsSocket(); }
int WEventSocket::Close() { EventSelect(0); // turn off all event notifications return WSocket::Close(); }
long CIpSocket::WaitEvent( long x_lEventId, long x_lTimeout ) { #if defined( HTM_NOEPOLL ) return 0; #else // Must have a socket handle if ( !IsSocket() ) return 0; // Must have event handle if ( !IsEventHandle() || !m_pEventObject ) { if ( !CreateEventHandle() ) return 0; if ( !EventSelect() ) return 0; } // end if // +++ Ensure our event is being waited on? // Grab pointer to event object epoll_event *pev = (epoll_event*)m_pEventObject; // Check for default timeout if ( 0 > x_lTimeout ) x_lTimeout = (long)m_lTimeout; // Save start time unsigned int uEnd = time( 0 ) + x_lTimeout / 1000; for( ; ; ) // forever { // What's the event state if ( 0 == ( m_uEventState & x_lEventId ) ) { // Wait only for our specific event EventSelect( x_lEventId ); // Wait for events int nRes; do { nRes = epoll_wait( tcPtrToULong( m_hSocketEvent ), pev, eMaxEvents, x_lTimeout ); } while ( -1 == nRes && EINTR == errno ); if ( -1 == nRes ) { // Log error m_uLastError = errno; // Disconnected? m_uConnectState |= eCsError; // Just ditch if they aren't waiting for the close event m_uEventState |= eCloseEvent; if ( !( x_lEventId & eCloseEvent ) ) return 0; } // end if // Process all events if ( 0 < nRes ) for ( long i = 0; i < nRes; i++ ) { // Convert to windows flags unsigned long uFlags = FlagNixToWin( pev[ i ].events ); // Save the status of all events if ( pev[ i ].data.fd == tcPtrToULong( m_hSocket ) ) { pev[ i ].events = 0; for ( unsigned long uMask = 1; uMask < eAllEvents; uMask <<= 1 ) if ( uFlags & uMask ) { // Get bit offset unsigned long uOffset = GetEventBit( uMask ); // Save the event info m_uEventState |= uMask; m_uEventStatus[ uOffset ] = 0; // Attempt to detect connect error if ( 0 != ( uMask & eConnectEvent ) ) { /* +++ Nope, doesn't always work // use getpeername() to check for errors sockaddr_in sai; memset( &sai, 0, sizeof( sai ) ); socklen_t len = sizeof( sai ); if ( -1 == getpeername( tcPtrToULong( m_hSocket ), (sockaddr*)&sai, &len ) ) { m_uLastError = errno; m_uEventStatus[ uOffset ] = errno; m_uConnectState |= eCsError; } // end if */ /* +++ gives error : Resource temporarily unavailable char buf[ 1 ]; if ( -1 == recv( tcPtrToULong( m_hSocket ), buf, 0, 0 ) ) { m_uLastError = errno; m_uEventStatus[ uOffset ] = errno; m_uConnectState |= eCsError; } // end if */ } // Handle close event if ( 0 != ( uMask & eCloseEvent ) ) m_uConnectState &= ~eCsConnected; else m_uConnectState |= eCsActivity; // +++ Signal when we get a connect message // if ( 0 != ( ( EPOLLIN | EPOLLOUT ) & uMask ) ) // m_uConnectState |= 2; } // end if } // end if } // end for // !!! Kludge around missing connect message if ( !( m_uConnectState & eCsConnected ) && ( m_uConnectState & eCsActivity ) ) { m_uConnectState |= eCsConnected; // m_uConnectState &= ~eCsError; m_uEventState |= eConnectEvent; m_uEventStatus[ eConnectBit ] = 0; } // end if } // end if // Did our event go off? if ( 0 != ( m_uEventState & x_lEventId ) ) { // Get the first event unsigned long uBit = GetEventBit( x_lEventId & m_uEventState ); unsigned long uMask = 1 << uBit; // Acknowledge this event // m_uEventState &= ~uMask; // Save the error code if ( m_uEventStatus[ uBit ] ) m_uLastError = m_uEventStatus[ uBit ]; // Something is going on m_lActivity++; // We received the event return uMask; } // end if // Have we timed out? unsigned long uTick = time( 0 ); if ( uEnd <= uTick ) return 0; // Adjust timeout x_lTimeout = ( uEnd - uTick ) * 1000; } // end if // Can't get here... return 0; #endif }
long CIpSocket::WaitEvent( long x_lEventId, long x_uTimeout ) { #if defined( HTM_NOSOCKET2 ) return 0; #else // Must have a socket handle if ( !IsSocket() ) return 0; // Must have event handle if ( !IsEventHandle() ) { if ( !CreateEventHandle() || !EventSelect() ) return 0; } // end if if ( 0 > x_uTimeout ) x_uTimeout = m_lTimeout; // Save start time UINT uEnd = GetTickCount() + x_uTimeout; for( ; ; ) { // What's the event state if ( 0 == ( m_uEventState & x_lEventId ) ) { if ( x_uTimeout ) { // Wait for event // UINT uRet = WaitForSingleObject( m_hSocketEvent, x_uTimeout ); // Check for timeout or error // if ( uRet != WAIT_OBJECT_0 ) // return 0; } // end if // Reset the network event ResetEvent( m_hSocketEvent ); // Get network events WSANETWORKEVENTS wne; memset( &wne, 0, sizeof( wne ) ); if ( SOCKET_ERROR == WSAEnumNetworkEvents( (SOCKET)m_hSocket, m_hSocketEvent, &wne ) ) { m_uLastError = WSAGetLastError(); return 0; } // end if // Save the status of all events for ( unsigned int uMask = 1; uMask && uMask <= eAllEvents; uMask <<= 1 ) if ( wne.lNetworkEvents & uMask ) { // Get bit offset unsigned int uOffset = GetEventBit( uMask ); // Save the event info m_uEventState |= uMask; m_uEventStatus[ uOffset ] = wne.iErrorCode[ uOffset ]; // Signal activity m_uConnectState |= eCsActivity; // Signal when we get a connect message if ( 0 != ( FD_CONNECT & wne.lNetworkEvents ) ) { // Set connected status if ( !m_uEventStatus[ FD_CONNECT_BIT ] ) m_uConnectState |= eCsConnected; // Handle connect error else m_uLastError = m_uEventStatus[ FD_CONNECT_BIT ], m_uConnectState &= ~( eCsConnected | eCsActivity ); // Connecting process is over m_uConnectState &= ~eCsConnecting; } // end if // Check for socket close if ( 0 != ( FD_CLOSE & wne.lNetworkEvents ) ) m_uConnectState &= ~( eCsConnected | eCsActivity | eCsConnecting ); } // end if // !!! Kludge around missing connect message // If we're accepting a connection, we don't // get a connect message. ( At least on Windows ) if ( !( m_uConnectState & 2 ) && ( m_uConnectState & 1 ) ) { m_uConnectState |= eCsConnected; m_uConnectState &= ~eCsConnecting; wne.lNetworkEvents |= FD_CONNECT; m_uEventState |= FD_CONNECT; m_uEventStatus[ FD_CONNECT_BIT ] = 0; } // end if } // end if // Did our event go off? if ( 0 != ( m_uEventState & x_lEventId ) ) { // Get the first event unsigned int uBit = GetEventBit( x_lEventId & m_uEventState ); unsigned int uMask = 1 << uBit; // Acknowledge this event m_uEventState &= ~uMask; // Save the error code m_uLastError = m_uEventStatus[ uBit ]; // Something is going on m_lActivity++; // We received the event return uMask; } // end if // Have we timed out? unsigned int uTick = GetTickCount(); if ( uEnd <= uTick ) return 0; // Adjust timeout x_uTimeout = uEnd - uTick; } // end if // Can't get here... return 0; #endif }