Files
Sun1602/Server/Shop/ClientStub/WBANetwork/net/Socket.cpp
T
2022-10-26 12:25:11 +08:00

417 lines
8.0 KiB
C++

#include "stdafx.h"
#include <WBANetwork/common.h>
#include <WBANetwork/WBANetwork.h>
#include <WBANetwork/Net/Socket.h>
#include <WBANetwork/util/AsyncResult.h>
#include <mstcpip.h>
using namespace WBANetwork;
Socket::Socket()
: m_Socket( INVALID_SOCKET ),
m_ProtocolType( Protocol_None )
{
memset(m_szIpAddress, 0, sizeof(m_szIpAddress));
}
Socket::~Socket()
{
Close();
}
DWORD Socket::SetKeepAlive(u_long onoff, u_long KeepaliveTime, u_long Keepaliveinterval)
{
DWORD dwRet = 0;
if(INVALID_SOCKET != m_Socket)
{
tcp_keepalive kl;
kl.onoff = onoff;
kl.keepalivetime = KeepaliveTime;
kl.keepaliveinterval = Keepaliveinterval;
::WSAIoctl(m_Socket, SIO_KEEPALIVE_VALS, &kl , sizeof(tcp_keepalive), 0, 0, &dwRet, NULL, NULL);
}
return dwRet;
}
bool Socket::Create( ProtocolType type, bool overlapped )
{
if( INVALID_SOCKET != m_Socket ||
Protocol_None == type )
{
//_ASSERTE(!"Socket::Create");
return false;
}
m_ProtocolType = type;
switch( type )
{
case Protocol_TCP:
{
if( true == overlapped )
{
m_Socket = ::WSASocket( AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
0,
0,
WSA_FLAG_OVERLAPPED );
}
else
{
m_Socket = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
}
if( INVALID_SOCKET == m_Socket )
{
//_ASSERTE(!"Socket::Create");
return false;
}
::memset( &m_SockAddr, 0, sizeof( m_SockAddr ) );
}
break;
case Protocol_UDP:
{
if( true == overlapped )
{
m_Socket = ::WSASocket( AF_INET,
SOCK_DGRAM,
IPPROTO_UDP,
0,
0,
WSA_FLAG_OVERLAPPED );
}
else
{
m_Socket = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
}
if( INVALID_SOCKET == m_Socket )
{
//_ASSERTE(!"Socket::Create");
return false;
}
::memset( &m_SockAddr, 0, sizeof( m_SockAddr ) );
}
break;
}
return true;
}
bool Socket::IsClose()
{
if(INVALID_SOCKET == m_Socket) return true;
return false;
}
void Socket::Close()
{
if( INVALID_SOCKET == m_Socket )
{
return;
}
::closesocket( m_Socket );
m_Socket = INVALID_SOCKET;
m_ProtocolType = Protocol_None;
}
bool Socket::Attach( ProtocolType type, SOCKET handle, SocketAddr* addr )
{
if( Protocol_None != type )
{
m_Socket = handle;
m_ProtocolType = type;
}
if( 0 != addr )
{
if ( FAILED(StringCbPrintf(m_szIpAddress, sizeof(m_szIpAddress),
_T("%d.%d.%d.%d"),
addr->sin_addr.S_un.S_un_b.s_b1,
addr->sin_addr.S_un.S_un_b.s_b2,
addr->sin_addr.S_un.S_un_b.s_b3,
addr->sin_addr.S_un.S_un_b.s_b4 ) ))
{
//_ASSERTE(!"Socket::Attach StringCbPrintf");
}
::memcpy( &m_SockAddr, addr, sizeof( SocketAddr ) );
}
return true;
}
SOCKET Socket::Accept( DWORD ms, SocketAddr* addr )
{
if( NULL == addr )
{
//_ASSERTE(!"Socket::Accept");
return INVALID_SOCKET;
}
struct timeval timeout;
fd_set fds;
int len = sizeof( SocketAddr );
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 acceptedSocket = INVALID_SOCKET;
try
{
acceptedSocket = ::accept( m_Socket, ( struct sockaddr* )addr, &len );
if( 0 != addr )
{
if ( FAILED(StringCbPrintf(m_szIpAddress, sizeof(m_szIpAddress),
_T("%d.%d.%d.%d"),
addr->sin_addr.S_un.S_un_b.s_b1,
addr->sin_addr.S_un.S_un_b.s_b2,
addr->sin_addr.S_un.S_un_b.s_b3,
addr->sin_addr.S_un.S_un_b.s_b4 ) ))
{
//_ASSERTE(!"Socket::Accept StringCbPrintf");
}
}
else
{
throw ;
}
}
catch( ... )
{
return INVALID_SOCKET;
}
return acceptedSocket;
}
return INVALID_SOCKET;
}
bool Socket::Connect( char* ipAddress, unsigned short portNo )
{
if( NULL == ipAddress ||
INVALID_SOCKET == m_Socket )
{
//_ASSERTE(!"Socket::Connect");
return false;
}
fd_set fds;
FD_ZERO( &fds );
FD_SET( m_Socket, &fds );
::memset( &m_SockAddr, 0, sizeof( SocketAddr ) );
m_SockAddr.sin_family = AF_INET;
m_SockAddr.sin_addr.s_addr = ::inet_addr( ipAddress );
m_SockAddr.sin_port = ::htons( portNo );
int ret = ::connect( m_Socket,
( struct sockaddr* )&m_SockAddr,
sizeof( m_SockAddr ) );
if( SOCKET_ERROR == ret )
{
return false;
}
if ( FAILED(StringCbPrintf(m_szIpAddress, sizeof(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 ) ))
{
//_ASSERTE(!"Socket::Connect StringCbPrintf");
}
return true;
}
bool Socket::Bind( char* ipAddress, unsigned short portNo )
{
if( NULL == ipAddress ||
INVALID_SOCKET == m_Socket )
{
//_ASSERTE(!"Socket::Bind");
return false;
}
::memset( &m_SockAddr, 0, sizeof( m_SockAddr ) );
m_SockAddr.sin_family = AF_INET;
if( 0 == strcmp( ipAddress, "127.0.0.1" ) )
{
m_SockAddr.sin_addr.s_addr = htonl( INADDR_ANY );
}
else
{
m_SockAddr.sin_addr.s_addr = ::inet_addr( ipAddress );
}
m_SockAddr.sin_port = ::htons( portNo );
int ret = ::bind( m_Socket,
( const sockaddr* )&m_SockAddr,
sizeof( m_SockAddr ) );
if ( FAILED(StringCbPrintf(m_szIpAddress, sizeof(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 ) ))
{
//_ASSERTE(!"Socket::Connect StringCbPrintf");
}
return ( SOCKET_ERROR != ret );
}
bool Socket::Listen( int backLogCount )
{
return ( ::listen( m_Socket, backLogCount ) != SOCKET_ERROR );
}
int Socket::Send( PBYTE buffer, int length, AsyncResult* result )
{
WSABUF wsaBuf;
wsaBuf.buf = (char *)buffer;
wsaBuf.len = length;
int ret = ::WSASend( m_Socket,
&wsaBuf,
1,
&result->transBytes,
0,
( LPOVERLAPPED )result,
0 );
result->error = ERROR_SUCCESS;
if( SOCKET_ERROR == ret )
{
result->error = ::WSAGetLastError();
if( ERROR_IO_PENDING != result->error )
{
return 0;
}
}
return result->transBytes;
}
int Socket::Recv( PBYTE buffer, int bufSize, AsyncResult* result )
{
WSABUF wsaBuf;
wsaBuf.buf = (char *)buffer;
wsaBuf.len = bufSize;
DWORD flag = 0;
int ret = ::WSARecv( m_Socket,
&wsaBuf,
1,
&result->transBytes,
&flag,
( LPOVERLAPPED )result,
0 );
result->error = ERROR_SUCCESS;
if( SOCKET_ERROR == ret )
{
result->error = ::WSAGetLastError();
if( ERROR_IO_PENDING != result->error )
{
return 0;
}
}
return result->transBytes;
}
HANDLE Socket::GetNativeHandle()
{
HANDLE handle = (m_Socket == INVALID_SOCKET )
? INVALID_HANDLE_VALUE
: ( HANDLE )m_Socket;
return handle;
}
void Socket::GetBufferSize( int* sndBufSize, int* rcvBufSize )
{
if( NULL == sndBufSize ||
NULL == rcvBufSize )
{
//_ASSERTE(!"Socket::GetBufferSize");
return;
}
int len = sizeof( int );
::getsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, ( char* )sndBufSize, &len );
::getsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, ( char* )rcvBufSize, &len );
}
void Socket::SetReuseAddr()
{
BOOL reuse = TRUE;
::setsockopt( m_Socket,
SOL_SOCKET,
SO_REUSEADDR,
( const char* )&reuse,
sizeof( reuse ) );
}
void Socket::SetIoctlSocket()
{
unsigned long argp = 1;
::ioctlsocket( m_Socket, FIONBIO, &argp );
}
void Socket::SetLinger( bool flag )
{
LINGER opt =
{
flag, 0
};
::setsockopt( m_Socket, SOL_SOCKET, SO_LINGER, ( char* )&opt, sizeof( opt ) );
}
void Socket::SetKeepAlive( bool flag )
{
int argp = flag;
::setsockopt( m_Socket, SOL_SOCKET, SO_KEEPALIVE, ( char* )&argp, sizeof( argp ) );
}
void Socket::SetBufferSize( int sndBufSize, int rcvBufSize )
{
::setsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, ( char* )&sndBufSize, sizeof( int ) );
::setsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, ( char* )&rcvBufSize, sizeof( int ) );
}