直接贴代码
void CListenAction::Init()
{
// 初始化套接字库
if (!InitSocketLib())
{
TRACE(_T("初始化套接字库失败"));
return ;
}
// 创建服务器端监听套接字
SOCKET listenSocket;
listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == listenSocket)
{
TRACE(_T("socket error: %d\n"),WSAGetLastError());
return;
}
// 本地地址
SOCKADDR_IN localAddr;
localAddr.sin_family = AF_INET;
// 获取本机IP地址
char szIPBuf[100];
memset(szIPBuf, 0, 100);
CCommUtility::GetLocalIP(szIPBuf, sizeof(szIPBuf));
localAddr.sin_addr.S_un.S_addr = inet_addr(szIPBuf);
// 设置端口号
localAddr.sin_port = htons(SERVER_PORT);
INT iRetTmp = bind(listenSocket, (SOCKADDR *)&localAddr, sizeof(localAddr));
if (SOCKET_ERROR == iRetTmp)
{
TRACE(_T("bind error: %d\n"),WSAGetLastError());
return;
}
iRetTmp = listen(listenSocket, LISTEN_QUEUE_LENGTH);
if (SOCKET_ERROR == iRetTmp)
{
TRACE(_T("listen error: %d\n"),WSAGetLastError());
return;
}
// 添加监听主套接字到通信对象数组
SOCKET_OBJ socketObj;
socketObj.sd = listenSocket;
socketObj.emConnectType = LISTEN;
socketObj.emSocketType = TCP_SOCKET;
m_arraySocket.Add(socketObj);
// 添加监听事件到事件数组 关联事件
WSAEVENT listenEvent = WSACreateEvent();
int iRet = WSAEventSelect(listenSocket, listenEvent, FD_ACCEPT | FD_CLOSE);
if (iRet != 0)
{
TRACE(_T("WSAEventSelect failed: %d\n"),WSAGetLastError());
return;
}
m_arrayEvent.Add(listenEvent);
// 开始监听事件
StartListenEvent();
}
/// @brief 开始监听套接字事件
VOID CListenAction::StartListenEvent()
{
// 网络事件
WSANETWORKEVENTS netEvents;
// 返回索引
DWORD dwIndex = 0;
DWORD dwRetTemp;
// 循环等待网络事件
while (TRUE)
{
// 判断线程是否退出
dwRetTemp = WaitForSingleObject(m_ExitEvent.m_hObject, 0);
if (WAIT_OBJECT_0 == dwRetTemp)
{
// 退出
break;
}
// 第一个有事件的通信对象索引
dwIndex = WSAWaitForMultipleEvents(m_arrayEvent.GetCount(),
&m_arrayEvent[0],
FALSE,
NETWORK_EVENT_WAIT_TIME,
FALSE);
// 失败
if (WSA_WAIT_FAILED == dwIndex)
{
TRACE(_T("WSAWaitForMultipleEvents error: %d\n"),WSAGetLastError());
return;
}
else
{
if (WSA_WAIT_TIMEOUT != dwIndex)
{
dwIndex -= WSA_WAIT_EVENT_0;
for (INT i = dwIndex; i < m_arrayEvent.GetCount(); i++)
{
dwIndex = WSAWaitForMultipleEvents(1, &m_arrayEvent[i], FALSE, 0, FALSE);
if ((WSA_WAIT_FAILED != dwIndex) && (WSA_WAIT_TIMEOUT != dwIndex))
{
WSAEnumNetworkEvents(m_arraySocket[i].sd, m_arrayEvent[i], &netEvents);
if (netEvents.lNetworkEvents & FD_ACCEPT)
{
if (netEvents.iErrorCode[FD_ACCEPT_BIT] != 0)
{
TRACE(_T("FD_ACCEPT error: %d\n"),netEvents.iErrorCode[FD_ACCEPT_BIT]);
break;
}
// 接收请求连接的客户端
AcceptClientConnection(m_arraySocket[i].sd);
}
if (netEvents.lNetworkEvents & FD_READ)
{
if (netEvents.iErrorCode[FD_READ_BIT] != 0)
{
// 记录日志
TRACE(_T("FD_READ error: %d\n"),netEvents.iErrorCode[FD_READ_BIT]);
break;
}
// 报告数据到达事件
ReportDataArrive(i);
}
if (netEvents.lNetworkEvents & FD_CLOSE)
{
if (netEvents.iErrorCode[FD_READ_BIT] != 0)
{
// 记录日志
TRACE(_T("FD_CLOSE error: %d\n"),netEvents.iErrorCode[FD_CLOSE_BIT]);
break;
}
// 断开连接
DisConnect(m_arraySocket[i].sd);
}
}
else
{
TRACE(_T("WSAWaitForMultipleEvents error: %d\n"),WSAGetLastError());
}
}
}
else
{
TRACE(_T("time out\n"));
}
}
}
}