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; }
本文介绍了一个基于C++的监听线程实现方案,该线程负责接收客户端的连接请求,并通过完成端口机制进行高效处理。文章详细展示了如何使用`accept`函数来建立新的连接,以及如何通过策略判断是否接受特定的连接。

被折叠的 条评论
为什么被折叠?



