📄 iotcpmodule.cc
字号:
// SimpleTCPIOModule.cpp: implementation of the IOTCPModule class.
//
//////////////////////////////////////////////////////////////////////
//#include <platforms.h>
#include <winsock.h>
#include "server/strhandle.h"
#include "server/net/IOTCPModule.h"
#include "platform/event.h"
namespace CS
{
typedef struct __tcpsocket
{
SOCKET sock;
SOCKADDR_IN sockAddr;//rmt;
char szAddr[ADDR_MAX];
} TCPSOCKET;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//CS_IOHANDLER IOTCPModule::m_ioHandler;
static IOTCPModule gs_tcpIOModule;
IOTCPModule::IOTCPModule()
{
m_ioHandler.pGetError = GetError;
m_ioHandler.pClose = Close;
m_ioHandler.pConnect = Connect;
m_ioHandler.pFree = Free;
m_ioHandler.pListen = Listen;
m_ioHandler.pCheckAccept = CheckAccept;
m_ioHandler.pCheckSend = CheckSend;
m_ioHandler.pCheckRecv = CheckRecv;
m_ioHandler.pAccept = Accept;
m_ioHandler.pQuery = Query;
m_ioHandler.pRecvEx = RecvEx;
m_ioHandler.pSendEx = SendEx;
m_ioHandler.pRecv = Recv;
m_ioHandler.pSend = Send;
m_ioHandler.pInsert = Insert;
m_ioHandler.pRemove = Remove;
m_ioHandler.pGetConnectAddr = GetConnectAddr;
m_ioHandler.pGetNetAddress = GetNetAddress;
}
IOTCPModule::~IOTCPModule()
{
}
CS_IOHANDLER* IOTCPModule::GetIOHandler()
{
return &gs_tcpIOModule.m_ioHandler;
//return &m_ioHandler;
}
INT RPGAPI IOTCPModule::GetError(void *data)
{
data;
return WSAGetLastError();
}
int RPGAPI IOTCPModule::Insert()
{
// Initialize Winsock 1.1
WSADATA wsaData;
if(WSAStartup(MAKEWORD(1,1), &wsaData)!=0)
return E_IOFAILED;
if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup();
return E_IOFAILED;
}
return E_IOOK;
}
int RPGAPI IOTCPModule::Remove()
{
// Clean up Winsock 1.1
WSACleanup();
return E_IOOK;
}
void * RPGAPI IOTCPModule::Listen(char *svTarget)
{
TCPSOCKET *tcps;
////////////////////////////////////////////////////////
//address port处理
// Get listen port
int nPort=0;
in_addr bindAddr;
bindAddr.S_un.S_addr = INADDR_ANY;
if(svTarget==NULL)
{
//nPort=CConfig::GetCfgNum(CConfig::m_szTCPIOConfig,"Default Port");
return NULL;
}
else if(stricmp(svTarget,"RANDOM") != 0)
{
char svAdr[260],*svPort;
strncpy(svAdr,svTarget,260);
svPort = BreakString(svAdr,":");
if(svPort==NULL)
nPort=atoi(svAdr);
else
{
bindAddr.S_un.S_addr = inet_addr(svAdr);
nPort = atoi(svPort);
}
}//else
///////////////////////////////////////////////////
//生成监听socket
// Create listener socket
SOCKET sock;
sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sock==INVALID_SOCKET)
return NULL;
BOOL bValue;
bValue = TRUE;
setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(char *)&bValue,sizeof(BOOL));
bValue=TRUE;
setsockopt(sock,SOL_SOCKET,SO_DONTLINGER,(char *)&bValue,sizeof(BOOL));
///////////////////////////////////////////////////
//绑定socket、启动socket监听
// Bind socket and listen
SOCKADDR_IN sockAddr;
dMemset(&sockAddr,0,sizeof(SOCKADDR_IN));
sockAddr.sin_addr = bindAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons((WORD)nPort);
if(bind(sock,(SOCKADDR *) &sockAddr,sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
closesocket(sock);
return NULL;
}
if(listen(sock,SOMAXCONN) != 0)
{
closesocket(sock);
return NULL;
}
int namelen = sizeof(SOCKADDR_IN);
getsockname(sock, (SOCKADDR *)&sockAddr, &namelen);
// Allocate state structure
tcps = (TCPSOCKET*)dMalloc(sizeof(TCPSOCKET));
if(tcps==NULL)
{
closesocket(sock);
return NULL;
}
// Fill in state structure
tcps->sock = sock;
dMemset(&(tcps->sockAddr), 0, sizeof(SOCKADDR_IN));
///////////////////////////////////////////
//获取连接后IP地址
// Get connect address
if(bindAddr.S_un.S_addr == INADDR_ANY)
{
char svHostName[ADDR_MAX];
hostent *he;
in_addr *pAddr;
gethostname(svHostName,ADDR_MAX);
he = gethostbyname(svHostName);
if(he)
{
pAddr = (in_addr*)he->h_addr_list[0];
dSprintf(tcps->szAddr,ADDR_MAX,"%u.%u.%u.%u:%u",
pAddr->S_un.S_un_b.s_b1,
pAddr->S_un.S_un_b.s_b2,
pAddr->S_un.S_un_b.s_b3,
pAddr->S_un.S_un_b.s_b4,
ntohs(sockAddr.sin_port));
}
else
{
strcpy(tcps->szAddr,"No Connect Addr");
}
}
else
{
strncpy(tcps->szAddr,svTarget,ADDR_MAX);
}
return tcps;
}
BOOL RPGAPI IOTCPModule::CheckAccept(void *data)
{
// Check to see if this is a listening socket
TCPSOCKET *tcps = (TCPSOCKET*)data;
//检测是否有连接请求
// Check for connection
fd_set rdfds;
TIMEVAL tm = {0,0};
FD_ZERO(&rdfds);
FD_SET(tcps->sock,&rdfds);
return select(0,&rdfds,NULL,NULL,&tm) > 0;
}
void * RPGAPI IOTCPModule::Accept(void *data, char *svAddr, int nMaxLen)
{
TCPSOCKET *tcps = (TCPSOCKET*)data;
//接受新的socket请求
// Accept socket
SOCKADDR_IN sockAddr;
int len = sizeof(SOCKADDR_IN);
SOCKET sockNew;
sockNew = accept(tcps->sock, (SOCKADDR*)&sockAddr, &len);
if(sockNew==INVALID_SOCKET)
return NULL;
BOOL bValue;
bValue = TRUE;
setsockopt(sockNew, IPPROTO_TCP, TCP_NODELAY, (char*)&bValue, sizeof(BOOL));
bValue=TRUE;
setsockopt(sockNew, SOL_SOCKET, SO_DONTLINGER, (char*)&bValue, sizeof(BOOL));
//新建IO Socket对象
TCPSOCKET *ioSockNew = (TCPSOCKET*)dMalloc(sizeof(TCPSOCKET));
if(ioSockNew==NULL)
{
closesocket(sockNew);
return NULL;
}
ioSockNew->sock = sockNew;
ioSockNew->sockAddr = sockAddr;
//返回地址信息
if(nMaxLen > 16)
{
dSprintf(svAddr,ADDR_MAX, "%3u.%3u.%3u.%3u",
sockAddr.sin_addr.S_un.S_un_b.s_b1,
sockAddr.sin_addr.S_un.S_un_b.s_b2,
sockAddr.sin_addr.S_un.S_un_b.s_b3,
sockAddr.sin_addr.S_un.S_un_b.s_b4);
}
return ioSockNew;
}
void * RPGAPI IOTCPModule::Connect(char *svTarget)
{
//新建socket
// Create socket
SOCKET sock;
sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sock==INVALID_SOCKET)
return NULL;
BOOL bValue;
bValue = TRUE;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&bValue, sizeof(BOOL));
bValue = TRUE;
setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char*)&bValue, sizeof(BOOL));
//分解连接IP、端口
// Get target port
int nPort;
char svHost[ADDR_MAX],
*pPort;
strncpy(svHost,svTarget,ADDR_MAX);
for(pPort=svHost; ((*pPort)!=':') && ((*pPort)!=NULL); pPort++);
if((*pPort)==':')
{
*pPort = '\0';
pPort++;
nPort = atoi(pPort);
}
else
return NULL;//nPort=CConfig::GetCfgNum(CConfig::m_szTCPIOConfig,"Default Port");
//解析IP地址
// Resolve hostname
DWORD addr = inet_addr(svHost);
if(addr==INADDR_NONE)
{
hostent *he = gethostbyname(svHost);
if(he==NULL)
{
closesocket(sock);
return NULL;
}
addr = *(DWORD*)(he->h_addr_list[0]);
}
//创建IP地址信息
// Create socket address
SOCKADDR_IN sockAddr;
dMemset(&sockAddr,0,sizeof(SOCKADDR_IN));
sockAddr.sin_addr.S_un.S_addr = addr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons((WORD)nPort);
//连接远程主机
// Connect to remote host
if( connect(sock,(SOCKADDR *)&sockAddr,sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
closesocket(sock);
return NULL;
}
//返回TCPSocket信息
// Allocate internal state structure
TCPSOCKET *tcps = (TCPSOCKET*)dMalloc(sizeof(TCPSOCKET));
if(tcps==NULL)
{
closesocket(sock);
return NULL;
}
tcps->sock = sock;
tcps->sockAddr = sockAddr;
return tcps;
}
int RPGAPI IOTCPModule::Close(void *ios)
{
TCPSOCKET *tcps = (TCPSOCKET*)ios;
closesocket(tcps->sock);
dFree(tcps);
return E_IOOK;
}
char * RPGAPI IOTCPModule::Query()
{
return "TCPIO: TCP IO Module v1.0";
}
BOOL RPGAPI IOTCPModule::CheckRecv(void *data)
{
TCPSOCKET *tcps = (TCPSOCKET *)data;
// Check socket for readability
TIMEVAL tv = {0,0};
fd_set rfds;
int nRet;
FD_ZERO(&rfds);
FD_SET(tcps->sock,&rfds);
nRet = select(1,&rfds,NULL,NULL,&tv);//WSAENOTINITIALISED
return (nRet > 0);
}
int RPGAPI IOTCPModule::Recv(void *data, BYTE *pInData, int *pnInDataLen)
{
TCPSOCKET *tcps = (TCPSOCKET *)data;
//获取数据长度
// Get length of rest of data
int nRet;
int nPacketSize;
//nPacketSize = *pnInDataLen;
int nLenRecv;
//nLenRecv = recv(tcps->sock, (char*)&nPacketSize, sizeof(int), MSG_PEEK);
//if(nLenRecv <= 0)
// return SOCKET_ERROR;
//if(nLenRecv < sizeof(int))
// return 0;
//确保有数据存在
// Make sure we have the rest of the packet
DWORD len;
if(ioctlsocket(tcps->sock, FIONREAD, &len) == SOCKET_ERROR)
return E_IOFAILED;
if(len > *pnInDataLen || len > MaxPacketDataSize)
return E_IOINVALID;
nPacketSize = len;
//请除头信息
// Clear off the header
//nLenRecv = recv(tcps->sock, (char*)&nPacketSize, sizeof(int), 0);
//if(nLenRecv < sizeof(int))
// return SOCKET_ERROR;
//申请数据缓冲
// Allocate buffer for data
//BYTE *pBuffer = (BYTE*) dMalloc(nPacketSize);
//if(pBuffer == NULL)
//{
// *pInData = NULL;
// *pnInDataLen= 0;
// return SOCKET_ERROR;
//}
BYTE *pBuffer = pInData;
//接受数据包
// Receive data
char *pBufRecv = (char*) pBuffer;
int nLeftNum = nPacketSize;
do
{
nLenRecv = recv(tcps->sock, pBufRecv, nLeftNum, 0);
if(nLenRecv == SOCKET_ERROR)
{
dFree(pBuffer);
*pInData = NULL;
*pnInDataLen= 0;
return E_IOFAILED;
}
nLeftNum -= nLenRecv;
pBufRecv += nLenRecv;
if(nLeftNum > 0)
Sleep(RECV_IDLE);
} while(nLeftNum > 0);
// Pass data back to application
//*pInData = pBuffer;
*pnInDataLen= nPacketSize;
return E_IOOK;
}
int RPGAPI IOTCPModule::RecvEx(void *data, BYTE **pInData, int *pnInDataLen)
{
TCPSOCKET *tcps = (TCPSOCKET *)data;
//获取数据长度
// Get length of rest of data
int nRet;
int nPacketSize;
int nLenRecv;
nLenRecv = recv(tcps->sock, (char*)&nPacketSize, sizeof(int), MSG_PEEK);
if(nLenRecv <= 0)
return E_IOFAILED;
if(nLenRecv < sizeof(int))
return E_IOINVALID;
//确保有数据存在
// Make sure we have the rest of the packet
DWORD len;
if(ioctlsocket(tcps->sock, FIONREAD, &len) == SOCKET_ERROR)
return E_IOFAILED;
if(len < (sizeof(int) + nPacketSize))
return E_IOINVALID;
//请除头信息
// Clear off the header
nLenRecv = recv(tcps->sock, (char*)&nPacketSize, sizeof(int), 0);
if(nLenRecv < sizeof(int))
return E_IOFAILED;
//申请数据缓冲
// Allocate buffer for data
BYTE *pBuffer = (BYTE*) dMalloc(nPacketSize);
if(pBuffer == NULL)
{
*pInData = NULL;
*pnInDataLen= 0;
return E_IOFAILED;
}
//接受数据包
// Receive data
char *pBufRecv = (char*) pBuffer;
int nLeftNum = nPacketSize;
do
{
nLenRecv = recv(tcps->sock, pBufRecv, nLeftNum, 0);
if(nLenRecv == SOCKET_ERROR)
{
dFree(pBuffer);
*pInData = NULL;
*pnInDataLen= 0;
return E_IOFAILED;
}
nLeftNum -= nLenRecv;
pBufRecv += nLenRecv;
if(nLeftNum > 0)
Sleep(RECV_IDLE);
} while(nLeftNum > 0);
// Pass data back to application
*pInData = pBuffer;
*pnInDataLen= nPacketSize;
return E_IOOK;
}
BOOL RPGAPI IOTCPModule::CheckSend(void *data)
{
TCPSOCKET *tcps = (TCPSOCKET*)data;
//发送数据包
// Send packet
TIMEVAL tm;
fd_set wfds;
int ret;
tm.tv_sec = SEND_TIMEOUT;
tm.tv_usec = 0;
FD_ZERO(&wfds);
FD_SET(tcps->sock,&wfds);
ret = select(0,NULL,&wfds,NULL,&tm);
return (ret > 0);
}
int RPGAPI IOTCPModule::Send(void *data, BYTE *pData, int nDataLen)
{
AssertWarn(nDataLen <= MaxPacketDataSize, "需要小于最大包大小...");
int ret;
TCPSOCKET *tcps = (TCPSOCKET*)data;
//生成单一数据包
// Make single packet
void *pBufPacket = pData;//dMalloc( sizeof(int) + nDataLen);
if(pBufPacket == NULL)
return E_IOFAILED;
//填充数据包长度、数据包内容
// Send packet length
//dMemcpy(pBufPacket, &nDataLen, sizeof(int));
//dMemcpy((BYTE*)pBufPacket + sizeof(int), pData, nDataLen);
{
char *pBufSend = (char*)pBufPacket;
int nLeftNum = nDataLen;//+sizeof(int);
do
{
ret = send(tcps->sock, pBufSend, nLeftNum, 0);
if(ret==SOCKET_ERROR)
break;
nLeftNum -= ret;
pBufSend += ret;
if(nLeftNum > 0)
Sleep(SEND_IDLE);
} while(nLeftNum > 0);
//dFree(pBufPacket);
if(ret==SOCKET_ERROR)
return E_IOFAILED;
return E_IOOK;
}
//dFree(pBufPacket);
return ret;
}
int RPGAPI IOTCPModule::SendEx(void *data, BYTE *pData, int nDataLen)
{
int ret;
TCPSOCKET *tcps = (TCPSOCKET*)data;
//生成单一数据包
// Make single packet
void *pBufPacket = dMalloc( sizeof(int) + nDataLen);
if(pBufPacket == NULL)
return E_IOFAILED;
//填充数据包长度、数据包内容
// Send packet length
dMemcpy(pBufPacket, &nDataLen, sizeof(int));
dMemcpy((BYTE*)pBufPacket + sizeof(int), pData, nDataLen);
{
char *pBufSend = (char*)pBufPacket;
int nLeftNum = nDataLen+sizeof(int);
do
{
ret = send(tcps->sock, pBufSend, nLeftNum, 0);
if(ret==SOCKET_ERROR)
break;
nLeftNum -= ret;
pBufSend += ret;
if(nLeftNum > 0)
Sleep(SEND_IDLE);
} while(nLeftNum > 0);
dFree(pBufPacket);
if(ret==SOCKET_ERROR)
return E_IOFAILED;
return E_IOOK;
}
dFree(pBufPacket);
return ret;
}
void RPGAPI IOTCPModule::Free(void *data, BYTE *pBuffer)
{
if(pBuffer==NULL)
return;
dFree(pBuffer);
}
void* RPGAPI IOTCPModule::GetNetAddress(void *data)
{
TCPSOCKET *tcps = (TCPSOCKET*)data;
return &tcps->sockAddr;
}
int RPGAPI IOTCPModule::GetConnectAddr(void *data, char *svAddr, int nMaxLen)
{
TCPSOCKET *tcps = (TCPSOCKET*)data;
if(nMaxLen < 0)
return SOCKET_ERROR;
if(nMaxLen > ADDR_MAX)
nMaxLen = ADDR_MAX;
strncpy(svAddr, tcps->szAddr, nMaxLen);
return E_IOOK;
}
};//namespace CS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -