bcb专门为线程提供了tthread类,用向导可以快速生成,有例程,能够完成绝大部分功能
//Listen thread executant,for acceptor blocking
//监听(Accept)线程执行体,用来接受用户连接请求
//
//参数:
//lpParam:用户数据,完成端口管理类
unsigned WINAPI ListenerThread(LPVOID lpParam)
{
SOCKET sockAccept;
LPCONN_CTX lpConnCtx;
int nResult;
unsigned Result=0;//线程返回值
//还原参数
TtcpIOCP *pIOCPServer=(TtcpIOCP *)lpParam;
try
{
if(!pIOCPServer)//参数错误
{
Result=1;
}
if(!pIOCPServer->IOCPInvalid)
{//完成例程前置条件初始化失败/未成功
pIOCPServer->FRunningState=LS_SHUTDN;
Result=2;
}
if(INVALID_SOCKET==pIOCPServer->ListenSock)
{//监听Socket创建失败,或未创建成功
pIOCPServer->FRunningState=LS_SHUTDN;
Result=3;
}
//服务器预置状态为非关闭状态,并且前置参数全部正常则运行
while((pIOCPServer->TuningListenState>LS_SHUTDN)
&&(Result==0)
&&(pIOCPServer->FListenSock!=INVALID_SOCKET))
{
struct sockaddr_in RemoteAddr;
memset(&RemoteAddr,0,sizeof(sockaddr));
int AddrLen=sizeof(sockaddr);
//置服务实际运行状态为预期状态
pIOCPServer->FRunningState=pIOCPServer->TuningListenState;
//如果为工作态,则执行Accept阻塞
if(LS_WORK==pIOCPServer->TuningListenState)
{
//Accept阻塞,用来接受一个用户连接
sockAccept=accept(pIOCPServer->ListenSock,
(struct sockaddr FAR*)&RemoteAddr,
&AddrLen);
if(sockAccept==INVALID_SOCKET)
{
//网络错误
pIOCPServer->FRunningState=LS_SHUTDN;
Result=4;
break;
}
if(LS_WORK==pIOCPServer->TuningListenState)
{
bool bAccepted=true;
try
{
//发出OnAccept通知,同时取判决结果
//若被执行策略,则bAccepted为返回false
//则直接断开该连接
pIOCPServer->InternalOnAccept(ntohs(RemoteAddr.sin_port),
inet_ntoa(RemoteAddr.sin_addr),
bAccepted);
}
catch(...)
{
}
if(bAccepted)
{
//连接正常接受,则添加一个用户连接信息上下文
pIOCPServer->AddConnection(sockAccept,
ntohs(RemoteAddr.sin_port),
inet_ntoa(RemoteAddr.sin_addr));
}
else
{
//被执行策略,强制关闭连接
ForceCloseSocket(sockAccept,true);
}
}
}
}
}
__finally
{
if(pIOCPServer)
{
//置服务状态为关闭态,同时重置期望值
pIOCPServer->FRunningState=LS_SHUTDN;
pIOCPServer->FTuningListenState=pIOCPServer->FRunningState;
}
//结束线程
_endthreadex(Result);
}
//形式返回值
return Result;
}
-
C/C++ code
-
// Create Listen Socket to do accept loop // 创建监听线程 bool __fastcall TtcpIOCP::CreateListenThread( void ) { unsigned long Result; unsigned ThreadID; if (NULL != FListenThread) return false ; LPOVERLAPPEDEX lpOverlapEx = NULL; PostAcceptEx( this ,lpOverlapEx); lpOverlapEx = NULL; PostAcceptEx( this ,lpOverlapEx); lpOverlapEx = NULL; PostAcceptEx( this ,lpOverlapEx); lpOverlapEx = NULL; PostAcceptEx( this ,lpOverlapEx); lpOverlapEx = NULL; PostAcceptEx( this ,lpOverlapEx); // return true; FListenThread = (HANDLE)_beginthreadex(NULL, 0 , ListenerThread, this , CREATE_SUSPENDED, & ThreadID); if (NULL == FListenThread) { char Msg[MAX_PATH]; memset(Msg, 0 ,MAX_PATH); sprintf(Msg, " Can not complete with create thread!(Error:%d)/r/nThread terminate later... " , GetLastError()); MessageBox(GetActiveWindow(), Msg, " Thread Error " , MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND | MB_TOPMOST); ExitThread( - 1 ); return false ; } Result = ResumeThread(FListenThread); if (Result == 0xFFFFFFFF ) { TerminateThread(FListenThread, 1 ); CloseHandle(FListenThread); char Msg[MAX_PATH]; memset(Msg, 0 ,MAX_PATH); sprintf(Msg, " Can not resume thread(%d)!(Error:%d)/r/nThread terminate later... " , ThreadID, GetLastError()); MessageBox(GetActiveWindow(), Msg, " Thread Error " , MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND | MB_TOPMOST); ExitThread( - 1 ); FListenThread = NULL; return false ; } return true ; }