init
This commit is contained in:
417
sdk/system/CustomSocketLinux.cpp
Normal file
417
sdk/system/CustomSocketLinux.cpp
Normal file
@@ -0,0 +1,417 @@
|
||||
#include <cstring>
|
||||
#include <errno.h>
|
||||
#include "SocketConfig.h"
|
||||
|
||||
#ifdef CONFIG_USE_LINUX_SOCKET
|
||||
|
||||
using namespace wylib::inet::socket;
|
||||
|
||||
INT CCustomSocket::setBlockMode(const bool block)
|
||||
{
|
||||
u_long ulock;
|
||||
|
||||
if ( block == m_boBlock )
|
||||
return 0;
|
||||
|
||||
if ( m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
ulock = block ? 0 : 1;
|
||||
if ( ioctl( m_nSocket, FIONBIO, &ulock ) )
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
m_boBlock = block;
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID CCustomSocket::close()
|
||||
{
|
||||
if ( m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
if ( m_boConnected )
|
||||
{
|
||||
Disconnected();
|
||||
}
|
||||
shutdown(m_nSocket, SHUT_RDWR);
|
||||
::close(m_nSocket);
|
||||
m_nSocket = INVALID_SOCKET;
|
||||
}
|
||||
m_boConnected = false;
|
||||
m_boConnecting = false;
|
||||
m_boBlock = true;
|
||||
}
|
||||
|
||||
INT CCustomSocket::shutDown(const INT sd)
|
||||
{
|
||||
int nErr = 0;
|
||||
|
||||
if ( m_boConnected && m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
nErr = shutdown( m_nSocket, sd );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_boConnected = false;
|
||||
m_boConnecting = false;
|
||||
Disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::bind(const ULONG addr, const INT port)
|
||||
{
|
||||
INT nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
|
||||
memset(&addrin, 0, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
//addrin.sin_addr.s_addr = addr;
|
||||
addrin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
addrin.sin_port = htons((u_short)port);
|
||||
|
||||
int tmp =1;
|
||||
setsockopt(m_nSocket,SOL_SOCKET,SO_REUSEADDR,&tmp, sizeof(tmp));
|
||||
|
||||
nErr = ::bind( m_nSocket, (const sockaddr*)&addrin, sizeof(addrin) );
|
||||
//if ( nErr == 0 )
|
||||
{
|
||||
m_LocalAddr = addrin;
|
||||
}
|
||||
|
||||
//return nErr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::bind(const char * addr, const INT port)
|
||||
{
|
||||
INT nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
|
||||
memset(&addrin, 0, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = inet_addr(addr);
|
||||
addrin.sin_port = htons((u_short)port);
|
||||
int tmp=1;
|
||||
setsockopt(m_nSocket,SOL_SOCKET,SO_REUSEADDR,&tmp, sizeof(tmp));
|
||||
nErr = ::bind( m_nSocket, (const sockaddr*)&addrin, sizeof(addrin) );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_LocalAddr = addrin;
|
||||
}
|
||||
|
||||
return nErr;
|
||||
/*
|
||||
struct hostent *phost;
|
||||
|
||||
#ifdef UNICODE
|
||||
wylib::string::CWideString ws(addr);
|
||||
wylib::string::CAnsiString *as = ws.toAStr();
|
||||
phost = gethostbyname(*as);
|
||||
delete as;
|
||||
#else
|
||||
phost = gethostbyname(addr);
|
||||
#endif
|
||||
|
||||
if ( phost )
|
||||
{
|
||||
in_addr addr;
|
||||
addr.s_addr = *(u_long*)phost->h_addr_list[0];
|
||||
return bind( addr.s_addr, port );
|
||||
}
|
||||
return errno;
|
||||
*/
|
||||
}
|
||||
|
||||
INT CCustomSocket::getRecvBufSize(ULONG *size)
|
||||
{
|
||||
unsigned int oplen = sizeof(*size);
|
||||
return getsockopt( m_nSocket, SOL_SOCKET, SO_RCVBUF, (char*)size, &oplen );
|
||||
}
|
||||
|
||||
INT CCustomSocket::setRecvBufSize(ULONG size)
|
||||
{
|
||||
return setsockopt(m_nSocket, SOL_SOCKET, SO_RCVBUF, (const char*)&size, sizeof(size));
|
||||
}
|
||||
|
||||
INT CCustomSocket::getSendBufSize(ULONG *size)
|
||||
{
|
||||
unsigned int oplen = sizeof(*size);
|
||||
return getsockopt( m_nSocket, SOL_SOCKET, SO_SNDBUF, (char*)size, &oplen );
|
||||
}
|
||||
|
||||
INT CCustomSocket::setSendBufSize(ULONG size)
|
||||
{
|
||||
return setsockopt( m_nSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&size, sizeof(size) );
|
||||
}
|
||||
|
||||
INT CCustomSocket::listen(const INT backlog)
|
||||
{
|
||||
return ::listen( m_nSocket, backlog );
|
||||
}
|
||||
|
||||
int CCustomSocket::connect(const char * addr, const INT port)
|
||||
{
|
||||
struct hostent *phost = NULL;
|
||||
|
||||
#ifdef UNICODE
|
||||
wylib::string::CWideString ws(addr);
|
||||
wylib::string::CAnsiString *as = ws.toAStr();
|
||||
phost = gethostbyname(*as);
|
||||
delete as;
|
||||
#else
|
||||
phost = gethostbyname(addr);
|
||||
#endif
|
||||
|
||||
if ( phost )
|
||||
{
|
||||
in_addr addr_;
|
||||
addr_.s_addr = inet_addr(addr);//*(u_long*)(phost->h_addr_list[0]);
|
||||
return connect( addr_.s_addr, port );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CCustomSocket::accept(SOCKET *socket, unsigned long wait_msec, PSOCKADDR_IN addr)
|
||||
{
|
||||
int nErr;
|
||||
fd_set set;
|
||||
timeval tv;
|
||||
unsigned int addrsize;
|
||||
|
||||
FD_ZERO( &set );
|
||||
FD_SET( m_nSocket, &set );
|
||||
|
||||
tv.tv_sec = long(wait_msec / 1000);
|
||||
tv.tv_usec = long( (wait_msec %1000)* 1000);
|
||||
|
||||
nErr = select( int(m_nSocket + 1), &set, NULL, NULL, &tv );
|
||||
if ( nErr < 0 )
|
||||
return nErr;
|
||||
if ( nErr > 0 )
|
||||
{
|
||||
addrsize = sizeof(*addr);
|
||||
*socket = ::accept( m_nSocket, (sockaddr*)addr, &addrsize );
|
||||
if ( *socket == INVALID_SOCKET )
|
||||
{
|
||||
return nErr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SOCKET_ERROR - 1;
|
||||
}
|
||||
|
||||
INT CCustomSocket::connect(const ULONG addr, const INT port)
|
||||
{
|
||||
int nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
|
||||
memset(&addrin, 0, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = addr;
|
||||
addrin.sin_port = htons(port);
|
||||
|
||||
nErr = ::connect( m_nSocket, (sockaddr*)&addrin, sizeof(addrin) );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_boConnected = true;
|
||||
m_boConnecting = false;
|
||||
Connected();
|
||||
}
|
||||
else
|
||||
{
|
||||
nErr = errno;
|
||||
if ( nErr == ENOBUFS)
|
||||
{
|
||||
nErr = 0;
|
||||
m_boConnected = false;
|
||||
m_boConnecting = true;
|
||||
}
|
||||
}
|
||||
|
||||
return nErr;
|
||||
}
|
||||
|
||||
INT CCustomSocket::connect(const char * addr, const INT port, int timeout)
|
||||
{
|
||||
struct hostent *phost;
|
||||
|
||||
#ifdef UNICODE
|
||||
wylib::string::CWideString ws(addr);
|
||||
wylib::string::CAnsiString *as = ws.toAStr();
|
||||
phost = gethostbyname(*as);
|
||||
delete as;
|
||||
#else
|
||||
phost = gethostbyname(addr);
|
||||
#endif
|
||||
|
||||
if ( phost )
|
||||
{
|
||||
in_addr addr;
|
||||
addr.s_addr = *(u_long*)phost->h_addr_list[0];
|
||||
return connect( addr.s_addr, port, timeout);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
INT CCustomSocket::connect(const ULONG addr, const INT port, int timeout)
|
||||
{
|
||||
int nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
memset(&addrin, 0, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = addr;
|
||||
addrin.sin_port = htons(port);
|
||||
|
||||
// 超时需要在非阻塞下
|
||||
unsigned long mode = 1;
|
||||
ioctl(m_nSocket, FIONBIO, &mode);
|
||||
nErr = 0;
|
||||
if ( ::connect( m_nSocket, (sockaddr*)&addrin, sizeof(addrin) ) == 0 )
|
||||
{
|
||||
m_boConnected = true;
|
||||
m_boConnecting = false;
|
||||
Connected();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 设置回阻塞
|
||||
mode = 0;
|
||||
ioctl(m_nSocket, FIONBIO, &mode);
|
||||
|
||||
// 使用select超时connet
|
||||
struct timeval tm={timeout,0};
|
||||
fd_set wset;
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(m_nSocket, &wset);
|
||||
if( ::select(m_nSocket+1, NULL, &wset, NULL, &tm) > 0)
|
||||
{
|
||||
int error=-1, len=sizeof(int);
|
||||
getsockopt(m_nSocket, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
|
||||
if(error == 0)
|
||||
{
|
||||
m_boConnected = true;
|
||||
m_boConnecting = false;
|
||||
Connected();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行到这里说明连接不成功
|
||||
nErr = errno;
|
||||
if ( nErr == ENOBUFS)
|
||||
{
|
||||
nErr = 0;
|
||||
m_boConnected = false;
|
||||
m_boConnecting = true;
|
||||
}
|
||||
}
|
||||
return nErr;
|
||||
}
|
||||
|
||||
int CCustomSocket::createSocket(SOCKET *socket, const INT af, const int type, const int protocol)
|
||||
{
|
||||
*socket = ::socket( af, type, protocol );
|
||||
if ( *socket == INVALID_SOCKET )
|
||||
{
|
||||
return *socket;
|
||||
}
|
||||
m_nSocket = *socket ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 原来的recv的实现
|
||||
int nErr = ::recv( m_nSocket, (char*)buf, len, flags );
|
||||
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
close();
|
||||
}
|
||||
else if ( nErr < 0 )
|
||||
{
|
||||
if ( !m_boBlock )
|
||||
{
|
||||
nErr = errno;
|
||||
if ( nErr != ENOBUFS )
|
||||
{
|
||||
SocketError( nErr );
|
||||
nErr = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nErr = SOCKET_ERROR - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nErr;
|
||||
*/
|
||||
|
||||
int CCustomSocket::recv(LPVOID buf, INT size, const INT flags)
|
||||
{
|
||||
if ( !buf || size < 1) return 0;
|
||||
|
||||
int r = 0 ;
|
||||
r = ::recv(m_nSocket, buf, size, flags);
|
||||
if( r == 0 )
|
||||
{
|
||||
// 关闭连接
|
||||
close();
|
||||
return 0 ;
|
||||
}
|
||||
else if( r < 0 )
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
INT CCustomSocket::send(LPVOID buf, INT len, const INT flags)
|
||||
{
|
||||
int nRet, nErr;
|
||||
char *ptr = (char*)buf;
|
||||
|
||||
nRet = 0;
|
||||
while ( len > 0 )
|
||||
{
|
||||
nErr = ::send( m_nSocket, (char*)ptr, len, flags );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
nRet = 0;
|
||||
close();
|
||||
break;
|
||||
}
|
||||
else if ( nErr < 0 )
|
||||
{
|
||||
if ( !m_boBlock )
|
||||
{
|
||||
if ( errno == EINTR ) // 因为发生中断,中断处理后可以继续发送,所以此处应选择暂时退出函数, 然后再继续调用send进行接收数据
|
||||
{
|
||||
continue ;
|
||||
}
|
||||
else if(errno == EAGAIN)
|
||||
{
|
||||
Sleep(10);
|
||||
continue ;
|
||||
}
|
||||
|
||||
}
|
||||
nRet = nErr;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nRet += nErr;
|
||||
ptr += nErr;
|
||||
len -= nErr;
|
||||
}
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user