📄 socket.cpp
字号:
// Socket.cpp: implementation of the CSocketBase class.
//
//////////////////////////////////////////////////////////////////////
#include "Socket.h"
#include <string.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSocketBase::CSocketBase() :
m_hSocket(INVALID_SOCKET),
m_bConnected(false),
m_iType(SOCK_STREAM),
m_iTalkFlag(0)
{
memset(&m_sockaddr, 0, sizeof(m_sockaddr));
memset(&m_rsockaddr, 0, sizeof(m_rsockaddr));
}
CSocketBase::~CSocketBase()
{
if (m_bConnected) Close();
}
SOCKET CSocketBase::Create(int iType)
{
m_iType = iType;
if ( (m_hSocket=socket(AF_INET, iType, 0))==INVALID_SOCKET )
{
return m_hSocket;
}
return m_hSocket;
}
bool CSocketBase::ShutDown(int how)
{
if (shutdown(m_hSocket,how)==SOCKET_ERROR)
{
return false;
}
return true;
}
bool CSocketBase::Close(void)
{
if (closesocket(m_hSocket)==SOCKET_ERROR)
{
return false;
}
m_hSocket = INVALID_SOCKET;
m_bConnected = false;
memset( &m_sockaddr, 0, sizeof( sockaddr_in ) );
memset( &m_rsockaddr, 0, sizeof( sockaddr_in ) );
return true;
}
bool CSocketBase::Connect(const char* szRemote, unsigned int uiPort)
{
if (Connected()) return false;
if( NULL==szRemote||0==uiPort )
{
return false;
}
if (INVALID_SOCKET==m_hSocket)
{
Create(m_iType);
}
hostent *hostEnt=NULL;
long lIPAddress=0;
hostEnt = gethostbyname( szRemote );
if( hostEnt != NULL )
{
lIPAddress = ((in_addr*)hostEnt->h_addr)->s_addr;
m_sockaddr.sin_addr.s_addr = lIPAddress;
}
else
{
m_sockaddr.sin_addr.s_addr = inet_addr( szRemote );
}
m_sockaddr.sin_family = AF_INET;
m_sockaddr.sin_port = htons( uiPort );
if( connect(m_hSocket, (SOCKADDR*)&m_sockaddr, sizeof(m_sockaddr))==SOCKET_ERROR )
{
return false;
}
m_bConnected = true;
return true;
}
void CSocketBase::Attach(SOCKET s, sockaddr_in* sAddr)
{
m_hSocket = s;
if (sAddr)
memcpy(&m_rsockaddr, sAddr, sizeof(sockaddr_in));
}
int CSocketBase::Send(const char* szData, int iLen)
{
if( NULL==szData||0==iLen )
{
return SOCKET_ERROR;
}
if (1==m_iTalkFlag)
{
char buf[2];
recv(m_hSocket,buf,1,0);
m_iTalkFlag = 0;
}
int ret = send(m_hSocket, szData, iLen, 0);
if ( SOCKET_ERROR!=ret )
m_iTalkFlag = 1;
return ret;
}
int CSocketBase::Receive( char* szData, int iLen )
{
if( szData == NULL )
{
return SOCKET_ERROR;
}
if (-1==m_iTalkFlag)
{
char buf[2]={"1"};
send(m_hSocket, buf, 1, 0);
m_iTalkFlag = 0;
}
int ret = recv( m_hSocket, szData, iLen, 0 );
if ( SOCKET_ERROR!=ret )
m_iTalkFlag = -1;
return ret;
}
int CSocketBase::SendTo(const char* szData, int iLen, const SOCKADDR* pTo, int iToLen)
{
if(NULL==szData||0==iLen||NULL==pTo||0==iToLen )
{
return SOCKET_ERROR;
}
int ret = sendto(m_hSocket,szData,iLen,0,pTo,iToLen );
return ret;
}
int CSocketBase::ReceiveFrom(char* szData, int iLen, SOCKADDR* pFrom, socklen_t* piFromLen )
{
if( NULL==szData )
{
return SOCKET_ERROR;
}
int ret = recvfrom(m_hSocket, szData, iLen, 0, pFrom, piFromLen);
return ret;
}
char* CSocketBase::GetRemoteIP( char* szIP )
{
if( szIP == NULL )
return NULL;
socklen_t namelen = sizeof( m_rsockaddr );
if( getpeername( m_hSocket, (SOCKADDR*)&m_rsockaddr, &namelen ) == SOCKET_ERROR )
return NULL;
strcpy(szIP, inet_ntoa(m_rsockaddr.sin_addr));
return szIP;
}
char* CSocketBase::GetLocalIP( char* szIP )
{
if( szIP == NULL )
return NULL;
char hostname[128];
gethostname(hostname, 128);
struct hostent * pHost;
pHost = gethostbyname(hostname);
char *hostIP = inet_ntoa(*((struct in_addr*)pHost->h_addr_list[0]));
memcpy( szIP, hostIP, strlen(hostIP) );
szIP[strlen(hostIP)] = 0;
return szIP;
}
bool CSocketBase::SetSockOpt(int level, int optname, void *optval, int optlen)
{
if ( setsockopt(m_hSocket,level,optname,(char*)optval,optlen)==SOCKET_ERROR )
{
return false;
}
return true;
}
void CSocketBase::GraceShutDown(bool bSender)
{
char szBuf[512];
int nReady;
fd_set rset;
FD_ZERO(&rset);
timeval twait={0,100};
int iWaitCount = 0;
if (bSender) ShutDown(SD_SEND);
while(true)
{
if (iWaitCount++>20) break;
FD_SET(m_hSocket, &rset);
twait.tv_sec = 0; twait.tv_usec = 100;
nReady = select(m_hSocket+1, &rset, NULL, NULL, &twait);
if (0==nReady) //time out
{
continue;
}
if (SOCKET_ERROR==nReady)
break;
if (FD_ISSET(m_hSocket, &rset))
if (Receive(szBuf, 512)<=0)
break;
}
if (!bSender) ShutDown(SD_SEND);
}
bool CSocketBase::Select(int iHow, int iWaitTime)
{
fd_set rSet, wSet, eSet;
FD_ZERO(&rSet);
FD_ZERO(&wSet);
FD_ZERO(&eSet);
fd_set *prSet=NULL, *pwSet=NULL, *peSet=NULL;
int nReady;
timeval twait={0,iWaitTime*1000};
if (iHow & SELECT_READ)
{
prSet = &rSet;
FD_SET(m_hSocket, prSet);
}
if (iHow & SELECT_WRITE)
{
pwSet = &wSet;
FD_SET(m_hSocket, pwSet);
}
if (iHow & SELECT_EXCEPT)
{
peSet = &eSet;
FD_SET(m_hSocket, peSet);
}
nReady = select(m_hSocket+1, prSet, pwSet, peSet, &twait);
if (nReady<0)
return false;
if ( (iHow&SELECT_READ)&&(FD_ISSET(m_hSocket, prSet)) ||
(iHow&SELECT_WRITE)&&(FD_ISSET(m_hSocket, pwSet)) ||
(iHow&SELECT_EXCEPT)&&(FD_ISSET(m_hSocket, peSet)) )
{
return true;
}
return false;
}
void CSocketBase::SendUDP(const char* szMsg, int length, const char* szIP, unsigned int uiPort)
{
CSocketBase sock;
sock.Create(SOCK_DGRAM);
const int bCast=1;
sock.SetSockOpt(SOL_SOCKET, SO_BROADCAST, (void*)&bCast, sizeof(bCast));
sockaddr_in bcAddr;
bcAddr.sin_family = AF_INET;
bcAddr.sin_port = htons(uiPort);
bcAddr.sin_addr.s_addr = inet_addr(szIP);
sock.SendTo(szMsg, length, (const SOCKADDR*)&bcAddr, sizeof(bcAddr));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -