CEventSocket 0.1修正版
来源:互联网 发布:unity3d就业前景 编辑:程序博客网 时间:2024/06/08 02:56
对CEventSocket做了些修改,主要是原来close时,清理socket和事件很容易造成同步问题。
修改后的清理方案为将close的socket,事件不再移除出数组,而是置为无效状态,并不绑定事件。在新加socket时扫描无效空位,在空位中插入新socket。这样避免了清除socket时对其他socket的移动而造成同步问题。
另外添加了些注释说明,大部分用法和CAsyncSocket差不多,但是不需要窗口,而且各个函数做了个int nNum参数表示socket序号。
目前是单线程版本,未使用线程池,最多操作64个socket。
多线程的以后完善。
以下代码:
//EventSocket.h
#pragma once
#include <WinSock2.h>
enum THREADSTATE...{
sPause = 0
,sRun
,sBusy
,sDelay
,sStop
,sDead
};
class CEventSocket
...{
protected:
int sAf,sType,sProtocol,sPort; //socket地址族,类型,协议 ,监听端口
THREADSTATE nWorkThreadState; //工作线程状态
long sNetworkEvents; //关联事件
SOCKET m_SocketArr[MAXIMUM_WAIT_OBJECTS];
WSAEVENT m_EventArr[MAXIMUM_WAIT_OBJECTS];
CRITICAL_SECTION csSockArr; //socket数组访问临界区
public:
int m_iTotalConn; //socket计数
CEventSocket(void);
~CEventSocket(void);
/**//*
初始化套接字库
*/
static bool PI_COMM_CLASS_EXT __stdcall EventSocketInit(WSADATA* lpwsaData = NULL);
protected:
/**//*
工作线程
*/
static DWORD WINAPI WorkThread(LPVOID lpObject);
protected:
/**//*
处理接口,nNum为触发事件的socket序号,nErrorCode为响应错误代码,无错误为0
*/
//FD_READ
virtual void OnReceive(int nNum,int /**//*nErrorCode*/);
//FD_SEND
virtual void OnSend(int nNum,int /**//*nErrorCode*/);
//FD_OOB
virtual void OnOutOfBandData(int nNum,int /**//*nErrorCode*/);
//FD_ACCEPT
virtual void OnAccept(int nNum,int /**//*nErrorCode*/);
//FD_CONNECT
virtual void OnConnect(int nNum,int /**//*nErrorCode*/);
//FD_CLOSE
virtual void OnClose(int nNum,int /**//*nErrorCode*/);
//等待超时ms毫秒,即ms毫秒内无网络事件
virtual void OnTimeOut(int ms);
public:
/**//*
创建工作线程,socket类型和关联事件
af: 地址族 PF_INET
type: socket类型 SOCK_STREAM orSOCK_DGRAM
protocl: 协议族
NetworkEvents: 关联事件
*/
virtual bool Create(int af = AF_INET,int type = SOCK_STREAM,int protocol = IPPROTO_IP,long NetworkEvents = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
/**//*
如果传入INVALID_SOCKET则创建新套接字,
如果传入有效套接字则绑定传入套接字
返回新套接字的序号
*/
virtual int NewSocket(SOCKET s=INVALID_SOCKET); //添加套接字
/**//*
监听端口nPort,返回监听套接字序号
*/
virtual int NewLisSock(int nPort,int nConnectionBacklog=5); //添加监听套接字
/**//*
设置工作线程状态
*/
bool SetState(THREADSTATE state);
/**//*
获取工作线程状态
*/
THREADSTATE GetState(void);
static int PASCAL GetLastError();
//以下为socket相关操作,可参看msdn CAsyncSocket,不同的是多了参数int nNum,表示要操作的socket序号
public:
bool Listen(int nNum=0,int nConnectionBacklog=5);
virtual SOCKET Accept(int nNum=0,SOCKADDR* lpSockAddr=NULL, int* nSockAddrLen=NULL);
bool Bind(int nNum,UINT nSocketPort , LPSTR lpszSocketAddress = NULL);
bool Bind (int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen);
bool Connect(int nNum,LPCTSTR lpszHostAddress, UINT nHostPort);
bool Connect(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen);
virtual int Send(int nNum,const void* lpBuf, int nBufLen, int nFlags=0);
int SendTo(int nNum,const void* lpBuf, int nBufLen,
UINT nHostPort, LPSTR lpszHostAddress = NULL, int nFlags = 0);
int SendTo(int nNum,const void* lpBuf, int nBufLen,
const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags = 0);
virtual int Receive(int nNum,void* lpBuf, int nBufLen, int nFlags=0);
int ReceiveFrom(int nNum,void* lpBuf, int nBufLen,
char* rSocketAddress, UINT& rSocketPort, int nFlags = 0);
int ReceiveFrom(int nNum,void* lpBuf, int nBufLen,
SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0);
bool GetPeerName(int nNum,CString& rPeerAddress, UINT& rPeerPort);
bool GetPeerName(int nNum,SOCKADDR* lpSockAddr, int* lpSockAddrLen);
bool GetSockName(int nNum,CString& rSocketAddress, UINT& rSocketPort);
bool GetSockName(int nNum,SOCKADDR* lpSockAddr, int* lpSockAddrLen);
bool SetSockOpt(int nNum,int nOptionName, const void* lpOptionValue,
int nOptionLen, int nLevel = SOL_SOCKET);
bool GetSockOpt(int nNum,int nOptionName, void* lpOptionValue,
int* lpOptionLen, int nLevel = SOL_SOCKET);
bool IOCtl(int nNum,long lCommand, DWORD* lpArgument);
bool EventSelect(int nNum,long Events=FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
int ShutDown(int nNum,int nHow);
virtual int Close(int nNum);
protected:
virtual int KillSocket(int nNum);
virtual int SendToHelper(int nNum,const void* lpBuf, int nBufLen,
const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags);
virtual int ReceiveFromHelper(int nNum,void* lpBuf, int nBufLen,
SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags);
virtual bool ConnectHelper(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen);
};
inline int CEventSocket::ShutDown(int nNum,int nHow)
...{ return shutdown(m_SocketArr[nNum],nHow); }
inline bool CEventSocket::Bind(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen)
...{ return (SOCKET_ERROR != bind(m_SocketArr[nNum], lpSockAddr, nSockAddrLen)); }
inline int CEventSocket::SendTo(int nNum,const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
...{ return SendToHelper(nNum,lpBuf, nBufLen, lpSockAddr, nSockAddrLen, nFlags); }
inline int CEventSocket::ReceiveFrom(int nNum,void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
...{ return ReceiveFromHelper(nNum,lpBuf, nBufLen, lpSockAddr, lpSockAddrLen, nFlags); }
inline bool CEventSocket::Listen(int nNum,int nConnectionBacklog)
...{ return (SOCKET_ERROR != listen(m_SocketArr[nNum], nConnectionBacklog)); }
inline bool CEventSocket::Connect(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen)
...{ return ConnectHelper(nNum,lpSockAddr, nSockAddrLen); }
inline int PASCAL CEventSocket::GetLastError()
...{ return WSAGetLastError(); }
inline bool CEventSocket::GetPeerName(int nNum,SOCKADDR* lpSockAddr, int* lpSockAddrLen)
...{ return (SOCKET_ERROR != getpeername(m_SocketArr[nNum], lpSockAddr, lpSockAddrLen)); }
inline bool CEventSocket::GetSockName(int nNum,SOCKADDR* lpSockAddr, int* lpSockAddrLen)
...{ return (SOCKET_ERROR != getsockname(m_SocketArr[nNum], lpSockAddr, lpSockAddrLen)); }
inline bool CEventSocket::SetSockOpt(int nNum,int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel)
...{ return (SOCKET_ERROR != setsockopt(m_SocketArr[nNum], nLevel, nOptionName, (LPCSTR)lpOptionValue, nOptionLen)); }
inline bool CEventSocket::GetSockOpt(int nNum,int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel)
...{ return (SOCKET_ERROR != getsockopt(m_SocketArr[nNum], nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen)); }
inline bool CEventSocket::IOCtl(int nNum,long lCommand, DWORD* lpArgument)
...{ return (SOCKET_ERROR != ioctlsocket(m_SocketArr[nNum], lCommand, lpArgument)); }
#pragma once
#include <WinSock2.h>
enum THREADSTATE...{
sPause = 0
,sRun
,sBusy
,sDelay
,sStop
,sDead
};
class CEventSocket
...{
protected:
int sAf,sType,sProtocol,sPort; //socket地址族,类型,协议 ,监听端口
THREADSTATE nWorkThreadState; //工作线程状态
long sNetworkEvents; //关联事件
SOCKET m_SocketArr[MAXIMUM_WAIT_OBJECTS];
WSAEVENT m_EventArr[MAXIMUM_WAIT_OBJECTS];
CRITICAL_SECTION csSockArr; //socket数组访问临界区
public:
int m_iTotalConn; //socket计数
CEventSocket(void);
~CEventSocket(void);
/**//*
初始化套接字库
*/
static bool PI_COMM_CLASS_EXT __stdcall EventSocketInit(WSADATA* lpwsaData = NULL);
protected:
/**//*
工作线程
*/
static DWORD WINAPI WorkThread(LPVOID lpObject);
protected:
/**//*
处理接口,nNum为触发事件的socket序号,nErrorCode为响应错误代码,无错误为0
*/
//FD_READ
virtual void OnReceive(int nNum,int /**//*nErrorCode*/);
//FD_SEND
virtual void OnSend(int nNum,int /**//*nErrorCode*/);
//FD_OOB
virtual void OnOutOfBandData(int nNum,int /**//*nErrorCode*/);
//FD_ACCEPT
virtual void OnAccept(int nNum,int /**//*nErrorCode*/);
//FD_CONNECT
virtual void OnConnect(int nNum,int /**//*nErrorCode*/);
//FD_CLOSE
virtual void OnClose(int nNum,int /**//*nErrorCode*/);
//等待超时ms毫秒,即ms毫秒内无网络事件
virtual void OnTimeOut(int ms);
public:
/**//*
创建工作线程,socket类型和关联事件
af: 地址族 PF_INET
type: socket类型 SOCK_STREAM orSOCK_DGRAM
protocl: 协议族
NetworkEvents: 关联事件
*/
virtual bool Create(int af = AF_INET,int type = SOCK_STREAM,int protocol = IPPROTO_IP,long NetworkEvents = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
/**//*
如果传入INVALID_SOCKET则创建新套接字,
如果传入有效套接字则绑定传入套接字
返回新套接字的序号
*/
virtual int NewSocket(SOCKET s=INVALID_SOCKET); //添加套接字
/**//*
监听端口nPort,返回监听套接字序号
*/
virtual int NewLisSock(int nPort,int nConnectionBacklog=5); //添加监听套接字
/**//*
设置工作线程状态
*/
bool SetState(THREADSTATE state);
/**//*
获取工作线程状态
*/
THREADSTATE GetState(void);
static int PASCAL GetLastError();
//以下为socket相关操作,可参看msdn CAsyncSocket,不同的是多了参数int nNum,表示要操作的socket序号
public:
bool Listen(int nNum=0,int nConnectionBacklog=5);
virtual SOCKET Accept(int nNum=0,SOCKADDR* lpSockAddr=NULL, int* nSockAddrLen=NULL);
bool Bind(int nNum,UINT nSocketPort , LPSTR lpszSocketAddress = NULL);
bool Bind (int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen);
bool Connect(int nNum,LPCTSTR lpszHostAddress, UINT nHostPort);
bool Connect(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen);
virtual int Send(int nNum,const void* lpBuf, int nBufLen, int nFlags=0);
int SendTo(int nNum,const void* lpBuf, int nBufLen,
UINT nHostPort, LPSTR lpszHostAddress = NULL, int nFlags = 0);
int SendTo(int nNum,const void* lpBuf, int nBufLen,
const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags = 0);
virtual int Receive(int nNum,void* lpBuf, int nBufLen, int nFlags=0);
int ReceiveFrom(int nNum,void* lpBuf, int nBufLen,
char* rSocketAddress, UINT& rSocketPort, int nFlags = 0);
int ReceiveFrom(int nNum,void* lpBuf, int nBufLen,
SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0);
bool GetPeerName(int nNum,CString& rPeerAddress, UINT& rPeerPort);
bool GetPeerName(int nNum,SOCKADDR* lpSockAddr, int* lpSockAddrLen);
bool GetSockName(int nNum,CString& rSocketAddress, UINT& rSocketPort);
bool GetSockName(int nNum,SOCKADDR* lpSockAddr, int* lpSockAddrLen);
bool SetSockOpt(int nNum,int nOptionName, const void* lpOptionValue,
int nOptionLen, int nLevel = SOL_SOCKET);
bool GetSockOpt(int nNum,int nOptionName, void* lpOptionValue,
int* lpOptionLen, int nLevel = SOL_SOCKET);
bool IOCtl(int nNum,long lCommand, DWORD* lpArgument);
bool EventSelect(int nNum,long Events=FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
int ShutDown(int nNum,int nHow);
virtual int Close(int nNum);
protected:
virtual int KillSocket(int nNum);
virtual int SendToHelper(int nNum,const void* lpBuf, int nBufLen,
const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags);
virtual int ReceiveFromHelper(int nNum,void* lpBuf, int nBufLen,
SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags);
virtual bool ConnectHelper(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen);
};
inline int CEventSocket::ShutDown(int nNum,int nHow)
...{ return shutdown(m_SocketArr[nNum],nHow); }
inline bool CEventSocket::Bind(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen)
...{ return (SOCKET_ERROR != bind(m_SocketArr[nNum], lpSockAddr, nSockAddrLen)); }
inline int CEventSocket::SendTo(int nNum,const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
...{ return SendToHelper(nNum,lpBuf, nBufLen, lpSockAddr, nSockAddrLen, nFlags); }
inline int CEventSocket::ReceiveFrom(int nNum,void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
...{ return ReceiveFromHelper(nNum,lpBuf, nBufLen, lpSockAddr, lpSockAddrLen, nFlags); }
inline bool CEventSocket::Listen(int nNum,int nConnectionBacklog)
...{ return (SOCKET_ERROR != listen(m_SocketArr[nNum], nConnectionBacklog)); }
inline bool CEventSocket::Connect(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen)
...{ return ConnectHelper(nNum,lpSockAddr, nSockAddrLen); }
inline int PASCAL CEventSocket::GetLastError()
...{ return WSAGetLastError(); }
inline bool CEventSocket::GetPeerName(int nNum,SOCKADDR* lpSockAddr, int* lpSockAddrLen)
...{ return (SOCKET_ERROR != getpeername(m_SocketArr[nNum], lpSockAddr, lpSockAddrLen)); }
inline bool CEventSocket::GetSockName(int nNum,SOCKADDR* lpSockAddr, int* lpSockAddrLen)
...{ return (SOCKET_ERROR != getsockname(m_SocketArr[nNum], lpSockAddr, lpSockAddrLen)); }
inline bool CEventSocket::SetSockOpt(int nNum,int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel)
...{ return (SOCKET_ERROR != setsockopt(m_SocketArr[nNum], nLevel, nOptionName, (LPCSTR)lpOptionValue, nOptionLen)); }
inline bool CEventSocket::GetSockOpt(int nNum,int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel)
...{ return (SOCKET_ERROR != getsockopt(m_SocketArr[nNum], nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen)); }
inline bool CEventSocket::IOCtl(int nNum,long lCommand, DWORD* lpArgument)
...{ return (SOCKET_ERROR != ioctlsocket(m_SocketArr[nNum], lCommand, lpArgument)); }
//EventSocket.cpp
#include "stdafx.h"
#include "EventSocket.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma comment(lib, "ws2_32.lib")
bool __stdcall CEventSocket::EventSocketInit(WSADATA* lpwsaData)
...{
WSADATA wsaData;
if (lpwsaData == NULL)
lpwsaData = &wsaData;
WORD wVersionRequested = MAKEWORD(1, 1);
int nResult = WSAStartup(wVersionRequested, lpwsaData);
if (nResult != 0)
return FALSE;
if (LOBYTE(lpwsaData->wVersion) != 1 || HIBYTE(lpwsaData->wVersion) != 1)
...{
WSACleanup();
return FALSE;
}
return TRUE;
}
CEventSocket::CEventSocket(void)
...{
m_iTotalConn = 0;
SetState(sRun);
memset(m_SocketArr,INVALID_SOCKET,sizeof(SOCKET)*MAXIMUM_WAIT_OBJECTS);
memset(m_EventArr,NULL,sizeof(WSAEVENT)*MAXIMUM_WAIT_OBJECTS);
InitializeCriticalSection(&csSockArr);
}
bool CEventSocket::Create(int af,int type,int protocol,long NetworkEvents)
...{
sNetworkEvents = NetworkEvents;
sProtocol = protocol;
sType = type;
sAf = af;
CreateThread(NULL, 0,WorkThread,this, 0, NULL);
return true;
}
CEventSocket::~CEventSocket(void)
...{
SetState(sStop);
while (nWorkThreadState != sDead)
...{
Sleep(10);
}
DeleteCriticalSection(&csSockArr);
}
DWORD WINAPI CEventSocket::WorkThread(LPVOID lpObject)
...{
int ret, index,nErrorCode;
WSANETWORKEVENTS NetworkEvents;
CEventSocket *EventSock=(CEventSocket*) lpObject;
while (EventSock->nWorkThreadState!=sStop)
...{
EnterCriticalSection(&EventSock->csSockArr);
ret = WSAWaitForMultipleEvents(EventSock->m_iTotalConn, EventSock->m_EventArr, FALSE, 1000, FALSE);
if (ret == WSA_WAIT_FAILED )
...{
Sleep(100);
LeaveCriticalSection(&EventSock->csSockArr);
continue;
}
if (ret == WSA_WAIT_TIMEOUT)
...{
EventSock->OnTimeOut(1000);
LeaveCriticalSection(&EventSock->csSockArr);
continue;
}
index = ret - WSA_WAIT_EVENT_0;
/**//*
套接字无效时重置事件,临时方案
改为在close时重设事件,但没有测试是否有效,先保留这里。
*/
if (EventSock->m_SocketArr[index] == INVALID_SOCKET)
...{
WSAResetEvent(EventSock->m_EventArr[index]);
LeaveCriticalSection(&EventSock->csSockArr);
continue;
}
WSAEnumNetworkEvents(EventSock->m_SocketArr[index], EventSock->m_EventArr[index], &NetworkEvents);
if (NetworkEvents.lNetworkEvents & FD_READ)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_READ_BIT];
EventSock->OnReceive(index,nErrorCode);
}
if (NetworkEvents.lNetworkEvents & FD_WRITE)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_WRITE_BIT];
EventSock->OnSend(index,nErrorCode);
}
if (NetworkEvents.lNetworkEvents & FD_OOB)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_OOB_BIT];
EventSock->OnOutOfBandData(index,nErrorCode);
}
if (NetworkEvents.lNetworkEvents & FD_CONNECT)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_CONNECT_BIT];
EventSock->OnConnect(index,nErrorCode);
}
//添加和删除socket之前出临界区,否则会两次进入临界区而卡死
LeaveCriticalSection(&EventSock->csSockArr);
if (NetworkEvents.lNetworkEvents & FD_ACCEPT)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_ACCEPT_BIT];
EventSock->OnAccept(index,nErrorCode);
}
if (NetworkEvents.lNetworkEvents & FD_CLOSE)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_CLOSE_BIT];
EventSock->OnClose(index,nErrorCode);
}
if(EventSock->nWorkThreadState==sPause)
Sleep(100);
}
EventSock->nWorkThreadState = sDead;
return 0;
}
int CEventSocket::NewSocket(SOCKET s)
...{
EnterCriticalSection(&csSockArr);
if (m_SocketArr[m_iTotalConn] != INVALID_SOCKET || m_iTotalConn>=MAXIMUM_WAIT_OBJECTS)
...{
LeaveCriticalSection(&csSockArr);
return false;
}
int iSock;
for (iSock = 0;iSock<MAXIMUM_WAIT_OBJECTS;iSock++)
...{
if (m_SocketArr[iSock] == INVALID_SOCKET)
...{
if (s==INVALID_SOCKET)
...{
m_SocketArr[iSock]=socket(sAf,sType,sProtocol);
}else ...{
m_SocketArr[iSock]=s;
}
break;
}
}
if (iSock == MAXIMUM_WAIT_OBJECTS)
...{
if (s != INVALID_SOCKET)
...{
closesocket(s);
}
return -1;
}
if (iSock >= m_iTotalConn)
...{
m_iTotalConn = iSock +1;
}
if(m_EventArr[iSock]==NULL)
...{
m_EventArr[iSock]=WSACreateEvent();
}
EventSelect(iSock,sNetworkEvents);
LeaveCriticalSection(&csSockArr);
return iSock;
}
int CEventSocket::NewLisSock(int nPort,int nConnectionBacklog)
...{
int nLisSockNum;
if (0==nPort)
SetLastError(WSAEINVAL);
nLisSockNum = NewSocket();
if (nLisSockNum<0)
...{
return -1;
}
EventSelect(nLisSockNum,FD_ACCEPT|FD_CLOSE);
if (!Bind(nLisSockNum,nPort))
...{
return -1;
}
if (!Listen(nLisSockNum, nConnectionBacklog))
...{
return -1;
}
return nLisSockNum;
};
SOCKET CEventSocket::Accept(int nNum,SOCKADDR* lpSockAddr, int* nSockAddrLen)
...{
return accept(m_SocketArr[nNum],lpSockAddr,nSockAddrLen);
}
bool CEventSocket::Bind(int nNum,UINT nSocketPort, LPSTR lpszSocketAddress)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
if (lpszSocketAddress == NULL)
...{
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
}
else
...{
DWORD lResult = inet_addr(lpszSocketAddress);
if (lResult == INADDR_NONE)
...{
WSASetLastError(WSAEINVAL);
return FALSE;
}
sockAddr.sin_addr.s_addr = lResult;
}
sockAddr.sin_port = htons((u_short)nSocketPort);
return Bind(nNum,(SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
bool CEventSocket::Connect(int nNum,LPCTSTR lpszHostAddress, UINT nHostPort)
...{
if (lpszHostAddress == NULL)
...{
return FALSE;
}
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
...{
LPHOSTENT lphost;
lphost = gethostbyname(lpszHostAddress);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
...{
WSASetLastError(WSAEINVAL);
return FALSE;
}
}
sockAddr.sin_port = htons((u_short)nHostPort);
return Connect(nNum,(SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
bool CEventSocket::ConnectHelper(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen)
...{
return connect(m_SocketArr[nNum], lpSockAddr, nSockAddrLen) != SOCKET_ERROR;
}
int CEventSocket::Send(int nNum,const void* lpBuf, int nBufLen, int nFlags)
...{
return send(m_SocketArr[nNum], (LPSTR)lpBuf, nBufLen, nFlags);
}
int CEventSocket::Receive(int nNum,void* lpBuf, int nBufLen, int nFlags)
...{
return recv(m_SocketArr[nNum], (LPSTR)lpBuf, nBufLen, nFlags);
}
int CEventSocket::SendTo(int nNum,const void* lpBuf, int nBufLen, UINT nHostPort, LPSTR lpszHostAddress, int nFlags)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
if (lpszHostAddress == NULL)
sockAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
else
...{
sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
...{
LPHOSTENT lphost;
lphost = gethostbyname(lpszHostAddress);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
...{
WSASetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
}
}
sockAddr.sin_port = htons((u_short)nHostPort);
return SendTo(nNum,lpBuf, nBufLen, (SOCKADDR*)&sockAddr, sizeof(sockAddr), nFlags);
}
int CEventSocket::SendToHelper(int nNum,const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
...{
return sendto(m_SocketArr[nNum], (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, nSockAddrLen);
}
int CEventSocket::ReceiveFrom(int nNum,void* lpBuf, int nBufLen, char* rSocketAddress, UINT& rSocketPort, int nFlags)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
int nResult = ReceiveFrom(nNum,lpBuf, nBufLen, (SOCKADDR*)&sockAddr, &nSockAddrLen, nFlags);
if(nResult != SOCKET_ERROR)
...{
rSocketPort = ntohs(sockAddr.sin_port);
rSocketAddress = inet_ntoa(sockAddr.sin_addr);
}
return nResult;
}
int CEventSocket::ReceiveFromHelper(int nNum,void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
...{
return recvfrom(m_SocketArr[nNum], (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, lpSockAddrLen);
}
//关闭套接字 重置事件
int CEventSocket::Close(int nNum)
...{
if (nNum >= m_iTotalConn)
...{
return -1;
}
if (m_SocketArr[nNum] != INVALID_SOCKET)
...{
int ret = closesocket(m_SocketArr[nNum]);
}
KillSocket(nNum);
WSAResetEvent(m_EventArr[nNum]);
return nNum;
}
int CEventSocket::KillSocket(int nNum)
...{
EnterCriticalSection(&csSockArr);
m_SocketArr[nNum]= INVALID_SOCKET;
if (nNum == m_iTotalConn -1)
...{
m_iTotalConn--;
}
LeaveCriticalSection(&csSockArr);
TRACE("Socket %d Killed!Return %d",nNum,nNum);
return nNum;
}
bool CEventSocket::GetPeerName(int nNum,CString& rPeerAddress, UINT& rPeerPort)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
bool bResult = GetPeerName(nNum,(SOCKADDR*)&sockAddr, &nSockAddrLen);
if (bResult)
...{
rPeerPort = ntohs(sockAddr.sin_port);
rPeerAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
bool CEventSocket::GetSockName(int nNum,CString& rSocketAddress, UINT& rSocketPort)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
bool bResult = GetSockName(nNum,(SOCKADDR*)&sockAddr, &nSockAddrLen);
if (bResult)
...{
rSocketPort = ntohs(sockAddr.sin_port);
rSocketAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
bool CEventSocket::EventSelect(int nNum,long Events)
...{
if(m_SocketArr[nNum] == INVALID_SOCKET)
...{
WSASetLastError(WSAENOTSOCK);
return false;
}
return WSAEventSelect(m_SocketArr[nNum],m_EventArr[nNum], Events) != SOCKET_ERROR;
}
bool CEventSocket::SetState(THREADSTATE state)
...{
nWorkThreadState=state;
return true;
}
THREADSTATE CEventSocket::GetState(void)
...{
return nWorkThreadState;
}
void CEventSocket::OnReceive(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnSend(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnOutOfBandData(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnAccept(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnConnect(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnClose(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnTimeOut(int ms)
...{
}
#include "stdafx.h"
#include "EventSocket.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma comment(lib, "ws2_32.lib")
bool __stdcall CEventSocket::EventSocketInit(WSADATA* lpwsaData)
...{
WSADATA wsaData;
if (lpwsaData == NULL)
lpwsaData = &wsaData;
WORD wVersionRequested = MAKEWORD(1, 1);
int nResult = WSAStartup(wVersionRequested, lpwsaData);
if (nResult != 0)
return FALSE;
if (LOBYTE(lpwsaData->wVersion) != 1 || HIBYTE(lpwsaData->wVersion) != 1)
...{
WSACleanup();
return FALSE;
}
return TRUE;
}
CEventSocket::CEventSocket(void)
...{
m_iTotalConn = 0;
SetState(sRun);
memset(m_SocketArr,INVALID_SOCKET,sizeof(SOCKET)*MAXIMUM_WAIT_OBJECTS);
memset(m_EventArr,NULL,sizeof(WSAEVENT)*MAXIMUM_WAIT_OBJECTS);
InitializeCriticalSection(&csSockArr);
}
bool CEventSocket::Create(int af,int type,int protocol,long NetworkEvents)
...{
sNetworkEvents = NetworkEvents;
sProtocol = protocol;
sType = type;
sAf = af;
CreateThread(NULL, 0,WorkThread,this, 0, NULL);
return true;
}
CEventSocket::~CEventSocket(void)
...{
SetState(sStop);
while (nWorkThreadState != sDead)
...{
Sleep(10);
}
DeleteCriticalSection(&csSockArr);
}
DWORD WINAPI CEventSocket::WorkThread(LPVOID lpObject)
...{
int ret, index,nErrorCode;
WSANETWORKEVENTS NetworkEvents;
CEventSocket *EventSock=(CEventSocket*) lpObject;
while (EventSock->nWorkThreadState!=sStop)
...{
EnterCriticalSection(&EventSock->csSockArr);
ret = WSAWaitForMultipleEvents(EventSock->m_iTotalConn, EventSock->m_EventArr, FALSE, 1000, FALSE);
if (ret == WSA_WAIT_FAILED )
...{
Sleep(100);
LeaveCriticalSection(&EventSock->csSockArr);
continue;
}
if (ret == WSA_WAIT_TIMEOUT)
...{
EventSock->OnTimeOut(1000);
LeaveCriticalSection(&EventSock->csSockArr);
continue;
}
index = ret - WSA_WAIT_EVENT_0;
/**//*
套接字无效时重置事件,临时方案
改为在close时重设事件,但没有测试是否有效,先保留这里。
*/
if (EventSock->m_SocketArr[index] == INVALID_SOCKET)
...{
WSAResetEvent(EventSock->m_EventArr[index]);
LeaveCriticalSection(&EventSock->csSockArr);
continue;
}
WSAEnumNetworkEvents(EventSock->m_SocketArr[index], EventSock->m_EventArr[index], &NetworkEvents);
if (NetworkEvents.lNetworkEvents & FD_READ)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_READ_BIT];
EventSock->OnReceive(index,nErrorCode);
}
if (NetworkEvents.lNetworkEvents & FD_WRITE)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_WRITE_BIT];
EventSock->OnSend(index,nErrorCode);
}
if (NetworkEvents.lNetworkEvents & FD_OOB)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_OOB_BIT];
EventSock->OnOutOfBandData(index,nErrorCode);
}
if (NetworkEvents.lNetworkEvents & FD_CONNECT)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_CONNECT_BIT];
EventSock->OnConnect(index,nErrorCode);
}
//添加和删除socket之前出临界区,否则会两次进入临界区而卡死
LeaveCriticalSection(&EventSock->csSockArr);
if (NetworkEvents.lNetworkEvents & FD_ACCEPT)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_ACCEPT_BIT];
EventSock->OnAccept(index,nErrorCode);
}
if (NetworkEvents.lNetworkEvents & FD_CLOSE)
...{
nErrorCode=NetworkEvents.iErrorCode[FD_CLOSE_BIT];
EventSock->OnClose(index,nErrorCode);
}
if(EventSock->nWorkThreadState==sPause)
Sleep(100);
}
EventSock->nWorkThreadState = sDead;
return 0;
}
int CEventSocket::NewSocket(SOCKET s)
...{
EnterCriticalSection(&csSockArr);
if (m_SocketArr[m_iTotalConn] != INVALID_SOCKET || m_iTotalConn>=MAXIMUM_WAIT_OBJECTS)
...{
LeaveCriticalSection(&csSockArr);
return false;
}
int iSock;
for (iSock = 0;iSock<MAXIMUM_WAIT_OBJECTS;iSock++)
...{
if (m_SocketArr[iSock] == INVALID_SOCKET)
...{
if (s==INVALID_SOCKET)
...{
m_SocketArr[iSock]=socket(sAf,sType,sProtocol);
}else ...{
m_SocketArr[iSock]=s;
}
break;
}
}
if (iSock == MAXIMUM_WAIT_OBJECTS)
...{
if (s != INVALID_SOCKET)
...{
closesocket(s);
}
return -1;
}
if (iSock >= m_iTotalConn)
...{
m_iTotalConn = iSock +1;
}
if(m_EventArr[iSock]==NULL)
...{
m_EventArr[iSock]=WSACreateEvent();
}
EventSelect(iSock,sNetworkEvents);
LeaveCriticalSection(&csSockArr);
return iSock;
}
int CEventSocket::NewLisSock(int nPort,int nConnectionBacklog)
...{
int nLisSockNum;
if (0==nPort)
SetLastError(WSAEINVAL);
nLisSockNum = NewSocket();
if (nLisSockNum<0)
...{
return -1;
}
EventSelect(nLisSockNum,FD_ACCEPT|FD_CLOSE);
if (!Bind(nLisSockNum,nPort))
...{
return -1;
}
if (!Listen(nLisSockNum, nConnectionBacklog))
...{
return -1;
}
return nLisSockNum;
};
SOCKET CEventSocket::Accept(int nNum,SOCKADDR* lpSockAddr, int* nSockAddrLen)
...{
return accept(m_SocketArr[nNum],lpSockAddr,nSockAddrLen);
}
bool CEventSocket::Bind(int nNum,UINT nSocketPort, LPSTR lpszSocketAddress)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
if (lpszSocketAddress == NULL)
...{
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
}
else
...{
DWORD lResult = inet_addr(lpszSocketAddress);
if (lResult == INADDR_NONE)
...{
WSASetLastError(WSAEINVAL);
return FALSE;
}
sockAddr.sin_addr.s_addr = lResult;
}
sockAddr.sin_port = htons((u_short)nSocketPort);
return Bind(nNum,(SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
bool CEventSocket::Connect(int nNum,LPCTSTR lpszHostAddress, UINT nHostPort)
...{
if (lpszHostAddress == NULL)
...{
return FALSE;
}
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
...{
LPHOSTENT lphost;
lphost = gethostbyname(lpszHostAddress);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
...{
WSASetLastError(WSAEINVAL);
return FALSE;
}
}
sockAddr.sin_port = htons((u_short)nHostPort);
return Connect(nNum,(SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
bool CEventSocket::ConnectHelper(int nNum,const SOCKADDR* lpSockAddr, int nSockAddrLen)
...{
return connect(m_SocketArr[nNum], lpSockAddr, nSockAddrLen) != SOCKET_ERROR;
}
int CEventSocket::Send(int nNum,const void* lpBuf, int nBufLen, int nFlags)
...{
return send(m_SocketArr[nNum], (LPSTR)lpBuf, nBufLen, nFlags);
}
int CEventSocket::Receive(int nNum,void* lpBuf, int nBufLen, int nFlags)
...{
return recv(m_SocketArr[nNum], (LPSTR)lpBuf, nBufLen, nFlags);
}
int CEventSocket::SendTo(int nNum,const void* lpBuf, int nBufLen, UINT nHostPort, LPSTR lpszHostAddress, int nFlags)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
if (lpszHostAddress == NULL)
sockAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
else
...{
sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
...{
LPHOSTENT lphost;
lphost = gethostbyname(lpszHostAddress);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
...{
WSASetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
}
}
sockAddr.sin_port = htons((u_short)nHostPort);
return SendTo(nNum,lpBuf, nBufLen, (SOCKADDR*)&sockAddr, sizeof(sockAddr), nFlags);
}
int CEventSocket::SendToHelper(int nNum,const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
...{
return sendto(m_SocketArr[nNum], (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, nSockAddrLen);
}
int CEventSocket::ReceiveFrom(int nNum,void* lpBuf, int nBufLen, char* rSocketAddress, UINT& rSocketPort, int nFlags)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
int nResult = ReceiveFrom(nNum,lpBuf, nBufLen, (SOCKADDR*)&sockAddr, &nSockAddrLen, nFlags);
if(nResult != SOCKET_ERROR)
...{
rSocketPort = ntohs(sockAddr.sin_port);
rSocketAddress = inet_ntoa(sockAddr.sin_addr);
}
return nResult;
}
int CEventSocket::ReceiveFromHelper(int nNum,void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
...{
return recvfrom(m_SocketArr[nNum], (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, lpSockAddrLen);
}
//关闭套接字 重置事件
int CEventSocket::Close(int nNum)
...{
if (nNum >= m_iTotalConn)
...{
return -1;
}
if (m_SocketArr[nNum] != INVALID_SOCKET)
...{
int ret = closesocket(m_SocketArr[nNum]);
}
KillSocket(nNum);
WSAResetEvent(m_EventArr[nNum]);
return nNum;
}
int CEventSocket::KillSocket(int nNum)
...{
EnterCriticalSection(&csSockArr);
m_SocketArr[nNum]= INVALID_SOCKET;
if (nNum == m_iTotalConn -1)
...{
m_iTotalConn--;
}
LeaveCriticalSection(&csSockArr);
TRACE("Socket %d Killed!Return %d",nNum,nNum);
return nNum;
}
bool CEventSocket::GetPeerName(int nNum,CString& rPeerAddress, UINT& rPeerPort)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
bool bResult = GetPeerName(nNum,(SOCKADDR*)&sockAddr, &nSockAddrLen);
if (bResult)
...{
rPeerPort = ntohs(sockAddr.sin_port);
rPeerAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
bool CEventSocket::GetSockName(int nNum,CString& rSocketAddress, UINT& rSocketPort)
...{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
bool bResult = GetSockName(nNum,(SOCKADDR*)&sockAddr, &nSockAddrLen);
if (bResult)
...{
rSocketPort = ntohs(sockAddr.sin_port);
rSocketAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
bool CEventSocket::EventSelect(int nNum,long Events)
...{
if(m_SocketArr[nNum] == INVALID_SOCKET)
...{
WSASetLastError(WSAENOTSOCK);
return false;
}
return WSAEventSelect(m_SocketArr[nNum],m_EventArr[nNum], Events) != SOCKET_ERROR;
}
bool CEventSocket::SetState(THREADSTATE state)
...{
nWorkThreadState=state;
return true;
}
THREADSTATE CEventSocket::GetState(void)
...{
return nWorkThreadState;
}
void CEventSocket::OnReceive(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnSend(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnOutOfBandData(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnAccept(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnConnect(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnClose(int nNum,int /**//*nErrorCode*/)
...{
}
void CEventSocket::OnTimeOut(int ms)
...{
}
- CEventSocket 0.1修正版
- 超级乘方【修正版】
- 计算器修正版
- 分段函数修正版
- 修正版Sqlserver
- 修正版---三角形类
- CloudFoundry.yml修正版
- Location解密修正版
- AFNetwork 2.5 修正版
- c++_ch04_02_修正版
- JS乗積計算例修正版
- 修正
- 修正
- 修正
- Midas中文修正版Up4
- 3Dmark06/PCMark修正版
- FinePlus v1.21 (修正版)
- 多层图像合成修正版
- 怎样下载优酷视频?
- 3月7日工作日志-zy
- Spring2.5支持OSGI、Aspect和完全基于注解配置
- 地磅称量系统之(59) 接收串口数据(串口控件的属性设置和超级终端的使用)
- 最近移植了Mocrochip的TCP/IP协议到ARM,共享之
- CEventSocket 0.1修正版
- HGE教程翻译(1)
- 页面之间传递参数得几种方法
- petshop4.0设计说明
- Linux 下串口编程
- excel 如何选择特定(倍数)的行
- 多线程 进度条 C# .net
- 项目经理是这样当的
- debug和release的区别