#include "stdafx.h" #include "NxSocket.h" NxSocket::NxSocket() : m_Socket( INVALID_SOCKET ) { } NxSocket::~NxSocket() { Close(); } bool NxSocket::Create( int nSocketType, bool bOverlapped ) { if( m_Socket != INVALID_SOCKET ) return false; int nProtocol = 0; if ( nSocketType == SOCK_STREAM ) { nProtocol = IPPROTO_TCP ; } else { nProtocol = IPPROTO_UDP ; } if( bOverlapped == true ) m_Socket = ::WSASocket( AF_INET, nSocketType , nProtocol, 0, 0, WSA_FLAG_OVERLAPPED ); else m_Socket = ::socket( AF_INET, nSocketType, nProtocol ); if( m_Socket == INVALID_SOCKET ) return false; ::memset( &m_SockAddr, 0, sizeof( m_SockAddr ) ); return true; } void NxSocket::Close() { if( m_Socket == INVALID_SOCKET ) return; ::closesocket( m_Socket ); m_Socket = INVALID_SOCKET; } bool NxSocket::Attach( SOCKET hSocket, sockaddr_in* pAddr ) { m_Socket = hSocket; if( pAddr != 0 ) { ::_stprintf_s( m_szIPAddress, _T("%d.%d.%d.%d"), pAddr->sin_addr.S_un.S_un_b.s_b1, pAddr->sin_addr.S_un.S_un_b.s_b2, pAddr->sin_addr.S_un.S_un_b.s_b3, pAddr->sin_addr.S_un.S_un_b.s_b4 ); ::memcpy( &m_SockAddr, pAddr, sizeof( sockaddr_in ) ); } bool reuse = true, keepAlive = true; ::setsockopt( m_Socket, SOL_SOCKET, SO_REUSEADDR, ( char* )&reuse, sizeof( reuse ) ); ::setsockopt( m_Socket, SOL_SOCKET, SO_KEEPALIVE, ( char* )&keepAlive, sizeof( keepAlive ) ); LINGER LingerStruct; LingerStruct.l_onoff = 1; LingerStruct.l_linger = 0; ::setsockopt( m_Socket, SOL_SOCKET, SO_LINGER, (char*)&LingerStruct, sizeof(LingerStruct) ); ::setsockopt( m_Socket, SOL_SOCKET, SO_LINGER, (char*)&LingerStruct, sizeof(LingerStruct) ); return true; } SOCKET NxSocket::Accept( DWORD ms, sockaddr_in* pAddr ) { struct timeval Timeout; fd_set fds; int nLen = sizeof( sockaddr_in ); FD_ZERO( &fds ); FD_SET( m_Socket, &fds ); Timeout.tv_sec = ms / 1000; Timeout.tv_usec = ms % 1000; if( ::select( 0, &fds, 0, 0, &Timeout ) == SOCKET_ERROR ) return INVALID_SOCKET; if( FD_ISSET( m_Socket, &fds ) ) { SOCKET hSocket; int size = sizeof( m_SockAddr ); hSocket = ::accept( m_Socket, ( struct sockaddr* )pAddr, &nLen ); ::_stprintf_s( m_szIPAddress, _T("%d.%d.%d.%d"), pAddr->sin_addr.S_un.S_un_b.s_b1, pAddr->sin_addr.S_un.S_un_b.s_b2, pAddr->sin_addr.S_un.S_un_b.s_b3, pAddr->sin_addr.S_un.S_un_b.s_b4 ); return hSocket; } return INVALID_SOCKET; } bool NxSocket::Connect( const TCHAR* szIPAddress, unsigned short nPortNo ) { if( m_Socket == INVALID_SOCKET ) return false; struct timeval t = { 1, 0 }; fd_set fds; FD_ZERO( &fds ); FD_SET( m_Socket, &fds ); ::memset( &m_SockAddr, 0, sizeof( sockaddr_in ) ); m_SockAddr.sin_family = AF_INET; #ifdef _UNICODE char szBuff[256]=""; NxWideStringToMultiString(szBuff, szIPAddress ); m_SockAddr.sin_addr.s_addr = ::inet_addr( szBuff ); #else m_SockAddr.sin_addr.s_addr = ::inet_addr( szIPAddress ); #endif m_SockAddr.sin_port = ::htons( nPortNo ); if( ::connect( m_Socket, ( struct sockaddr* )&m_SockAddr, sizeof( m_SockAddr ) ) == SOCKET_ERROR ) return false; ::_stprintf_s( m_szIPAddress, _T("%d.%d.%d.%d"), m_SockAddr.sin_addr.S_un.S_un_b.s_b1, m_SockAddr.sin_addr.S_un.S_un_b.s_b2, m_SockAddr.sin_addr.S_un.S_un_b.s_b3, m_SockAddr.sin_addr.S_un.S_un_b.s_b4 ); return true; } bool NxSocket::Bind( const TCHAR* szIPAddress, unsigned short nPortNo ) { int nError; ::memset( &m_SockAddr, 0, sizeof( m_SockAddr ) ); m_SockAddr.sin_family = AF_INET; m_SockAddr.sin_addr.s_addr = INADDR_ANY;//::inet_addr(szIPAddress); m_SockAddr.sin_port = ::htons( nPortNo ); nError = ::bind( m_Socket, ( const sockaddr* )&m_SockAddr, sizeof( m_SockAddr ) ); ::_stprintf_s( m_szIPAddress, _T("%d.%d.%d.%d"), m_SockAddr.sin_addr.S_un.S_un_b.s_b1, m_SockAddr.sin_addr.S_un.S_un_b.s_b2, m_SockAddr.sin_addr.S_un.S_un_b.s_b3, m_SockAddr.sin_addr.S_un.S_un_b.s_b4 ); return ( nError != SOCKET_ERROR ); } bool NxSocket::Listen( int nBackLogCount ) { return ( ::listen( m_Socket, nBackLogCount ) != SOCKET_ERROR ); } int NxSocket::Send( char* pBuffer, int nLength, NxAsyncEvent* pEvent ) { WSABUF wsaBuf; int ret; wsaBuf.buf = pBuffer; wsaBuf.len = nLength; ret = ::WSASend( m_Socket, &wsaBuf, 1, &pEvent->nTransBytes, 0, ( LPOVERLAPPED )pEvent, 0 ); pEvent->nError = ::WSAGetLastError(); if( ret == SOCKET_ERROR ) { if( pEvent->nError != ERROR_IO_PENDING && pEvent->nError != ERROR_SUCCESS ) return 0; } return pEvent->nTransBytes; } int NxSocket::Recv( char* pBuffer, int nBufSize, NxAsyncEvent* pEvent ) { WSABUF wsaBuf; DWORD bFlag; int ret; bFlag = 0; wsaBuf.buf = pBuffer; wsaBuf.len = nBufSize; ret = ::WSARecv( m_Socket, &wsaBuf, 1, &pEvent->nTransBytes, &bFlag, ( LPOVERLAPPED )pEvent, 0 ); pEvent->nError = ::WSAGetLastError(); if( ret == SOCKET_ERROR ) { if( pEvent->nError != ERROR_IO_PENDING && pEvent->nError != ERROR_SUCCESS ) return 0; } return pEvent->nTransBytes; } HANDLE NxSocket::GetNativeHandle() { return ( HANDLE )m_Socket; } void NxSocket::GetBufferSize( int* nSendBufSize, int* nRecvBufSize ) { int len = sizeof( int ); ::getsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, ( char* )nSendBufSize, &len ); ::getsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, ( char* )nRecvBufSize, &len ); } void NxSocket::SetReuseAddr() { BOOL reuse = TRUE; ::setsockopt( m_Socket, SOL_SOCKET, SO_REUSEADDR, ( const char* )&reuse, sizeof( reuse ) ); } void NxSocket::SetIoctlSocket() { unsigned long argp = 1; ::ioctlsocket( m_Socket, FIONBIO, &argp ); } void NxSocket::SetLinger( bool bFlag ) { LINGER opt = { bFlag, 0 }; ::setsockopt( m_Socket, SOL_SOCKET, SO_LINGER, ( char* )&opt, sizeof( opt ) ); } void NxSocket::SetKeepAlive( bool bFlag ) { int argp = bFlag; ::setsockopt( m_Socket, SOL_SOCKET, SO_KEEPALIVE, ( char* )&argp, sizeof( argp ) ); } void NxSocket::SetBufferSize( int nSendBufSize, int nRecvBufSize ) { ::setsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, ( char* )&nSendBufSize, sizeof( int ) ); ::setsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, ( char* )&nRecvBufSize, sizeof( int ) ); }