📄 sockserver.cpp
字号:
#include "stdafx.h"
#include "sockServer.h"
CSockServer::CSockServer(void)
{
sprintf( m_strIP, "NULL" );
m_dwPort = 0;
m_dwProtocol = SOCK_STREAM;
m_hEvent[0] = CreateEvent(NULL,0,0,0);
m_hEvent[1] = CreateEvent(NULL,0,0,0);
}
CSockServer::~CSockServer(void)
{
m_bRunState = false;
CloseHandle( m_hEvent[0] );
CloseHandle( m_hEvent[1] );
Cleanup();
}
bool CSockServer::Initialize(void)
{
WSADATA wsaData;
//建立winsock
if( WSAStartup( 0x0202 , &wsaData ) )
{
DebugMsg( "WSAStartup失败!\n" );
return false;
}
//判断版本
if( wsaData.wVersion != 0x0202 )
{
DebugMsg( "系统不支持Winsock 2.0!\n" );
WSACleanup();
return false;
}
return true;
}
void CSockServer::Cleanup(void)
{
//清除socket
if( m_sSocket != INVALID_SOCKET )
closesocket( m_sSocket );
//清除winsock
WSACleanup();
}
bool CSockServer::Create(const char* strIP, DWORD dwPort,DWORD dwProtocol)
{
sprintf( m_strIP, "%s", strIP );
m_dwPort = dwPort;
m_dwProtocol = dwProtocol;
m_sSocket = socket(PF_INET, m_dwProtocol, 0);
if(m_sSocket == INVALID_SOCKET)
{
DebugMsg("创建socket错误\n");
return false;
}
SOCKADDR_IN sockAddr;
memset( &sockAddr , 0 , sizeof( sockAddr ) );
sockAddr.sin_family = AF_INET;
if( m_strIP )
{
sockAddr.sin_addr.s_addr = inet_addr( m_strIP );
if( sockAddr.sin_addr.s_addr == INADDR_NONE )
{
WSASetLastError( WSAEINVAL );
DebugMsg("无法解析IP!\n");
return false;
}
}
else
{
sockAddr.sin_addr.s_addr = htonl( INADDR_ANY );
}
sockAddr.sin_port = htons( ( WORD )m_dwPort );
if( bind( m_sSocket , ( SOCKADDR * )&sockAddr , sizeof( sockAddr ) ) == SOCKET_ERROR )
{
DebugMsg("绑定错误\n");
return false;
}
return true;
}
bool CSockServer::Listen(DWORD dwMaxNumber)
{
//侦听
if( listen(m_sSocket,(int)dwMaxNumber) == SOCKET_ERROR )
{
DebugMsg("侦听失败了\n");
return false;
}
//设置事件选择
if( WSAEventSelect(m_sSocket,m_hEvent[0],FD_ACCEPT|FD_CLOSE) == SOCKET_ERROR )
{
DebugMsg("侦听事件选择失败\n");
return false;
}
//创建侦听线程
DWORD dwThreadID;
m_hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ListenThread,this,0,&dwThreadID);
if( m_hThread == NULL )
{
DebugMsg("创建侦听线程错误\n");
return false;
}
//创建服务端响应消息线程
m_hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ServerThread,this,0,&dwThreadID);
if( m_hThread == NULL )
{
DebugMsg("创建服务端响应消息线程错误\n");
return false;
}
return true;
}
bool CSockServer::Accept(void)
{
if(m_sSocket == INVALID_SOCKET)
{
DebugMsg("accept中socket失败!\n");
return false;
}
//生成一个新的客户端对象
CSockClient* pSocket = new CSockClient;
SOCKADDR_IN sockAddr;
int iLen = sizeof(sockAddr);
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
pSocket->SetSocket(accept(m_sSocket,(sockaddr*)&sockAddr,&iLen));
if(pSocket->GetSocket() == INVALID_SOCKET)
{
DebugMsg("accept连接失败!\n");
SAFE_DELETE(pSocket);
return false;
}
if(WSAEventSelect(pSocket->GetSocket(),pSocket->GetEvent()[0],FD_READ|FD_WRITE|FD_CLOSE) == SOCKET_ERROR )
{
DebugMsg("accept事件选择连接失败!\n");
SAFE_DELETE(pSocket);
return false;
}
pSocket->SetClientThread(m_pServerThreadMessage);
//添加到客户端列表
InstrSocket(pSocket);
pSocket->SetIP(inet_ntoa(sockAddr.sin_addr));
pSocket->SetPort((DWORD)ntohs(sockAddr.sin_port));
return true;
}
bool CSockServer::SendTcpAll(LPVOID lpBuffer,DWORD dwBufferLenght,DWORD dwFlags )
{
CheckList();
list < CSockClient* >::iterator Pointer;
for( Pointer = m_ClientList.begin(); Pointer != m_ClientList.end(); Pointer ++ )
{
CSockClient* Socket = * Pointer;
if( send( Socket->GetSocket() , (char*)lpBuffer , (int)dwBufferLenght , (int)dwFlags) == SOCKET_ERROR )
{
if( WSAGetLastError() != WSAEWOULDBLOCK )
return false;
}
}
return true;
}
bool CSockServer::CheckList(void)
{
list < CSockClient* >::iterator Pointer;
for( Pointer = m_ClientList.begin(); Pointer != m_ClientList.end(); Pointer ++ )
{
CSockClient* Socket = * Pointer;
if( !Socket->GetRunState() )
{
DeleteSocket(Socket);
SAFE_DELETE(Socket);
return true;
}
}
return true;
}
bool CSockServer::ListenThread(LPVOID lpParam)
{
CSockServer* pSocket = (CSockServer*)lpParam;
if( pSocket == NULL )
return false;
//进入事件枚举循环
while(1)
{
if(!pSocket->GetRunState())
{
DebugMsg("线程终于结束了\n");
return false;
}
//等等那些事件的设定了
if( WaitForMultipleObjects( 2 , pSocket->GetEvent() , false , 10 ) == 1 )
{
DebugMsg("服务端侦听线程事件没响应\n");
return false;
}
WSANETWORKEVENTS events;
//开try
try
{
// 枚举网络事件
if(WSAEnumNetworkEvents(pSocket->GetSocket(),pSocket->GetEvent()[0],&events))
{
DebugMsg("服务端侦听线程枚举网络事件错误\n");
return false;
}
if(events.lNetworkEvents != 0)
{
//当连接成功
if(events.lNetworkEvents == FD_ACCEPT)
{
pSocket->GetListenThread()(pSocket,FD_ACCEPT,0,(DWORD)events.iErrorCode[FD_ACCEPT_BIT]);
}
//当关闭套接字
if(events.lNetworkEvents == FD_CLOSE)
{
pSocket->GetListenThread()(pSocket,FD_CLOSE,0,(DWORD)events.iErrorCode[FD_CLOSE_BIT]);
}
}
}
catch(...)
{
static long oldtime = 0;
long newtime = timeGetTime();
if( newtime - oldtime >= 10000 )
{
oldtime = newtime;
DebugMsg("网络侦听超时,说不定是掉了\n");
}
}
}
return true;
}
bool CSockServer::ServerThread(LPVOID lpParam)
{
list <CSockClient*>::iterator Pointer;
CSockServer* pSocket = (CSockServer*)lpParam;
if(pSocket == NULL)
return false;
while(1)
{
pSocket->CheckList();
//历遍客户端
for( Pointer = pSocket->GetClientList()->begin(); Pointer != pSocket->GetClientList()->end(); Pointer ++ )
{
CSockClient* Socket = *Pointer;
if(!pSocket->GetRunState())
return false;
WSANETWORKEVENTS events;
try
{
// 枚举网络事件
if( WSAEnumNetworkEvents(Socket->GetSocket(),Socket->GetEvent()[0],&events))
{
DebugMsg("服务端消息线程枚举网络事件错误\n");
}
if( events.lNetworkEvents != 0 )
{
// 收到消息
if( events.lNetworkEvents == FD_READ )
{
Socket->GetClientThread()(Socket,FD_READ,Socket->GetBufferLength(),(DWORD)events.iErrorCode[FD_READ_BIT]);
}
if( events.lNetworkEvents == FD_WRITE )
{
Socket->GetClientThread()(Socket,FD_WRITE,0,(DWORD)events.iErrorCode[FD_WRITE_BIT]);
}
// 关闭套接字
if( events.lNetworkEvents == FD_CLOSE )
{
//Socket->SetRunState(false);
Socket->GetClientThread()(Socket,FD_CLOSE,0,(DWORD)events.iErrorCode[FD_CLOSE_BIT]);
}
}
else
{
// 检测数据缓冲中是否有数据存在
if(Socket->GetBufferLength())
{
Socket->GetClientThread()(Socket,FD_READ,Socket->GetBufferLength(),0);
}
}
}
catch(...)
{
static long old = 0;
long now = timeGetTime();
if( now - old >= 10000 )
{
old = now;
DebugMsg("服务器响应消息线程发生超时,说不定是掉了\n!");
}
}
}
Sleep(1);
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -