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 + -
显示快捷键?