cls_sock.cpp

来自「ABis无线接口全套资料」· C++ 代码 · 共 915 行 · 第 1/2 页

CPP
915
字号
/* ======================================================================== *\
 |
 |
 |  JOYIT Communication Technology
 |  Copyright (C)  2003-2006,  All Right Reserved.
 |
 |  Filename: cls_sock.cpp
 |  Environment: Red Hat Linux 7.2 & GNU C/C++ Compiler 2.96
 |				 Windows Microsoft Visual C/C++ 6.0
 |  Function description: 
 |		(1) CLS_Socket operating on TCP socket;
 |		(2) CLS_TCPSvr supply a TCP Server class;
 |		(3) CLS_TCPClient supply a TCP Client class;
 |		(4) CLS_UDP supply a UDP class
 |
\* ======================================================================== */

#ifdef _WIN32
#include "stdafx.h"
#include "cls_sock.h"
#pragma comment(lib,"ws2_32.lib")
#include <winsock2.h>
#else
#include "cls_sock.h"

extern "C"
{
#ifndef _STDLIB_H
#include <stdlib.h>
#endif

#ifndef _STDIO_H
#include <stdio.h>
#endif

#ifndef _ERRNO_H
#include <errno.h>
#endif

#ifndef _STRING_H
#include <string.h>
#endif

#ifndef _FCNTL_H
#include <fcntl.h>
#endif

#ifndef _UNISTD_H
#include <unistd.h>
#endif

#ifndef _SYS_SOCKET_H
#include <sys/socket.h>
#endif

#ifndef _NETDB_H
#include <netdb.h>
#endif

#ifndef _NETINET_IN_H
#include <netinet/in.h>
#endif

#ifndef _ARPA_INET_H
#include <arpa/inet.h>
#endif

#ifndef _SYS_SELECT_H
#include <sys/select.h>
#endif
};
#endif

#ifdef _WIN32
static int g_iSockCount=0;
#endif // ifdef _WIN32

int GetTCPLibVer(char *strVer)
{
	const char *strVerInfo=
"	TCP Class Library V1.0.0, Copyright (c) 2003-2006 by JOYIT communications\
implemented by socket library, supporting classes: CLS_Socket, CLS_TCPSvr,\
CLS_TCPClient, CLS_UDP.";

	strcpy(strVer, strVerInfo);
	return 0x00010000; // 1.0.0
}

CLS_Socket::CLS_Socket()
{
	m_iSocket=-1;
	m_iStatus=SS_UNUSED;
	m_iSocketError=0;
#ifdef _WIN32
	WSADATA wsaData;
	if(!g_iSockCount)
	{
		if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR) 
			WSACleanup();
	}
	g_iSockCount++;
#endif
}

CLS_Socket::CLS_Socket(int iSocket, int iStatus)
{
	m_iSocket=iSocket;
	m_iStatus=iStatus;
	m_iSocketError=0;
}

CLS_Socket::~CLS_Socket()
{
	CloseSocket();
#ifdef _WIN32
	g_iSockCount--;
	if(!g_iSockCount)
		WSACleanup();
#endif
}

int CLS_Socket::SetSockOpt(int iLevel, int iOptName, const char *pOptVal, int iOptLen)
{
	return setsockopt(m_iSocket, iLevel, iOptName, pOptVal, iOptLen);
};

int CLS_Socket::GetSockOpt(int iLevel, int iOptName, char *pOptVal, int * pOptLen)
{
	return getsockopt(m_iSocket, iLevel, iOptName, pOptVal, (socklen_t *)pOptLen);
}

int CLS_Socket::CreateSocket()
{
	if(m_iSocket>-1)
		CloseSocket();
	m_iSocket = socket(AF_INET, SOCK_STREAM, 0); 
	if(m_iSocket>-1)
		m_iStatus=SS_CREATED;

	return m_iSocket;
}

int CLS_Socket::CloseSocket()
{
	int iRet = 0;

	if (m_iSocket > 0) // To avoid repeat close.
	{
#ifdef _WIN32
		iRet=closesocket(m_iSocket);
#else
		iRet=close(m_iSocket);
#endif
	}

	m_iSocket=-1;
	m_iStatus=SS_UNUSED;

	return iRet;
}

int CLS_Socket::SetNonBlock(unsigned long iFlag)
{
#ifdef _WIN32
	if(ioctlsocket(m_iSocket, FIONBIO, &iFlag))
		return -1;
#else
	if(iFlag)
	if(fcntl(m_iSocket, F_SETFL, O_NONBLOCK))
		return -1;
#endif

	return 0;
}

int CLS_Socket::SetSocketProp()
{
	int iRet, iRet1;
	unsigned long iFlag;

	iFlag=1;
	iRet=setsockopt(m_iSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&iFlag, sizeof(iFlag));

	iFlag=TCP_SEND_BUFF;
	iRet1=setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (const char *)&iFlag, sizeof(iFlag));
	if(!iRet && !iRet1)
		iRet=0;
	else if(iRet1)
		iRet=-2;

	iFlag=TCP_RECV_BUFF;
	iRet=setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (const char *)&iFlag, sizeof(iFlag));
	if(!iRet && !iRet1)
		iRet=0;
	else if(iRet1)
		iRet=-3;

	return iRet;
}

int CLS_Socket::Bind(const char *strIP, int iPort)
{
	struct sockaddr_in sockAddr;
	unsigned long ulIP;

	memset(&sockAddr, 0, sizeof(sockAddr));
	sockAddr.sin_family = AF_INET;
	ulIP=inet_addr(strIP);
	sockAddr.sin_addr.s_addr = ulIP;
	sockAddr.sin_port = htons(iPort);

	if(bind(m_iSocket, (struct sockaddr*)&sockAddr, sizeof(sockAddr) )<0)
	{
		CloseSocket();
		return -1; 
	}

	m_iStatus=SS_BOUND;

	return 0;
}

// use this function after bind() for UDP or listen or connected for TCP
char *CLS_Socket::GetLocalHost(int *pPort)
{
	struct sockaddr_in localAddr;
	int iRet, iLen;

	iLen = sizeof(localAddr);
	iRet = getsockname(m_iSocket, (struct sockaddr *)&localAddr, (socklen_t *)&iLen);
	if(iRet < 0)
		  return NULL;

	*pPort=ntohs(localAddr.sin_port);
	return inet_ntoa(localAddr.sin_addr);
}

int CLS_Socket::SendData(void *pData, int iMaxLen)
{
	int iRet, iLen, i;
	char *p;

	i=0;
	iLen=0;
	p=(char *)pData;
	while(iLen<iMaxLen)
	{
		iRet=send(m_iSocket, p, iMaxLen-iLen, 0);
		if(iRet<0)
		{
#ifdef _WIN32
			m_iSocketError=GetLastError();
			if(m_iSocketError==WSAEWOULDBLOCK)
				iRet=0;
			else
			{
				CloseSocket();
				return -1;
			}			
#else
			m_iSocketError=errno;
			// if(m_iSocketError==EWOULDBLOCK||m_iSocketError==EINTR)
			if ((EWOULDBLOCK == m_iSocketError) // Modify 2006-01-24, by Wu jianjin.
				|| (EINTR == m_iSocketError) // 
				|| (EAGAIN == m_iSocketError)) // Ignore "Broken pipe" error.
			{
				iRet=0;
			}
			else
			{
				CloseSocket();
				return -1;	
			}
#endif
		}

		m_iSocketError=0;
		iLen+=iRet;
		if(iRet==0)
		{
			i++;
			if(i==MAX_TRY_SOCK)
			{
				CloseSocket();
				return -2;
			}
#ifdef _WIN32
			Sleep(SOCK_SLEEP);
#else
			usleep(SOCK_SLEEP);
#endif
		}
		p+=iRet;
	}

	return iLen;
}

int CLS_Socket::RecvData(void *pData, int iMaxLen)
{
	int iLen;

	iLen=recv(m_iSocket, (char *)pData, iMaxLen, 0);

	if(iLen<0)
	{
#ifdef _WIN32
		m_iSocketError=GetLastError( );
		if(m_iSocketError==WSAEWOULDBLOCK)
		{
			iLen=0;
			m_iSocketError=0;
		}
		else
		{
			CloseSocket( );
		}
#else
		m_iSocketError=errno;
		// if(m_iSocketError==EWOULDBLOCK||m_iSocketError==EINTR)
		if ((EWOULDBLOCK == m_iSocketError) // Modify 2006-01-24, by Wu jianjin.
			|| (EINTR == m_iSocketError) // 
			|| (EAGAIN == m_iSocketError)) // Ignore "Broken pipe" error.
		{
			iLen=0;
			m_iSocketError=0;
		}
		else
		{
			CloseSocket( );
		}
#endif
	}

	return iLen;
}

int CLS_Socket::SendTo(const char *strPeerAddr, int iPeerPort, void *pData, int iMaxLen)
{
	int iRet, iLen, i;
	char *p;
	struct sockaddr_in cliAddr;

	memset(&cliAddr, 0, sizeof(cliAddr));
	cliAddr.sin_family=AF_INET;
	cliAddr.sin_port=htons(iPeerPort);
	cliAddr.sin_addr.s_addr=inet_addr(strPeerAddr);

	i=0;
	iLen=0;
	p=(char *)pData;
	while(iLen<iMaxLen && i<MAX_TRY_SOCK)
	{
		iRet=sendto(m_iSocket, (const char *)p, iMaxLen-iLen, 0, (struct sockaddr *)&cliAddr, sizeof(cliAddr));
		if(iRet<0)
		{
#ifdef _WIN32
			m_iSocketError=GetLastError();
			if(m_iSocketError!=WSAEWOULDBLOCK)
			{
				CloseSocket();
				return -1;
			}
			iRet=0;
#else
			m_iSocketError=errno;
			// if(!(m_iSocketError==EWOULDBLOCK||m_iSocketError==EINTR))
			if ((EWOULDBLOCK == m_iSocketError) // Modify 2006-01-24, by Wu jianjin.
				|| (EINTR == m_iSocketError) // 
				|| (EAGAIN == m_iSocketError)) // Ignore "Broken pipe" error.
			{
				iRet=0;
			}
			else
			{
				CloseSocket();
				return -1;
			}
#endif
		}

		m_iSocketError=0;
		iLen+=iRet;
		if(iLen)
			i++;
		p+=iRet;
	}

	if(i==MAX_TRY_SOCK)
	{
		CloseSocket();
		return -2;
	}
	return iLen;
}

int CLS_Socket::RecvFrom(char *strPeerAddr, int *pPeerPort, void *pData, int iMaxLen)
{
	int iLen, iFromLen;
	struct sockaddr_in cliAddr;

	iFromLen=sizeof(cliAddr);
	iLen=recvfrom(m_iSocket, (char *)pData, iMaxLen, 0, (struct sockaddr *)&cliAddr, (socklen_t *)&iFromLen);
	if(iLen<0)
	{
#ifdef _WIN32
		m_iSocketError=GetLastError();
		if(m_iSocketError!=WSAEWOULDBLOCK)
		{
			CloseSocket();
			return -1;
		}
		iLen=0;
#else
		m_iSocketError=errno;
		//  if(!(m_iSocketError==EWOULDBLOCK||m_iSocketError==EINTR))
		if ((EWOULDBLOCK == m_iSocketError) // Modify 2006-01-24, by Wu jianjin.
			|| (EINTR == m_iSocketError) // 
			|| (EAGAIN == m_iSocketError)) // Ignore "Broken pipe" error.
		{
			iLen=0;
		}
		else
		{
			CloseSocket();
			return -1;
		}
#endif
	}
	else if(iLen>0)
	{
		strcpy(strPeerAddr, inet_ntoa(cliAddr.sin_addr));
		*pPeerPort=ntohs(cliAddr.sin_port);
	}

	m_iSocketError=0;
	return iLen;
}

int CLS_Socket::GetStatus()
{
	return m_iStatus;
}

CLS_TCPConnect::CLS_TCPConnect()
	:CLS_Socket()
{
	m_strIP[0]=0;
	m_iPort=-1;
	SetSocketProp();
	SetNonBlock();
}

CLS_TCPConnect::CLS_TCPConnect(int iSocket, const char *strIP, int iPort)
	:CLS_Socket(iSocket, SS_CONNECT)
{
	strcpy(m_strIP, strIP);
	m_iPort=iPort;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?