MFC基于select模型的套接字类之服务器(8)

4 停止服务器

CTCPSocket_Server类添加访问权限为public的成员函数StopServer()。在该函数中主要完成的工作是关闭“2.3 StartServer()函数”中提到了用于接受客户端连接的线程和用于接收客户端数据的线程。

4.1 结束接受客户端连接的线程

2.3 StartServer()函数”中提到,该线程由CTCPSocket_Server类的成员变量m_acceptthread_alive来控制。当该变量的值是false时,线程函数中的while()循环将退出,结束线程。

StopServer()函数中,首先将m_acceptthread_alive设置为false

m_acceptthread_alive = false;
接下来使用WaitForSingleObject() 函数等待该线程结束。

WaitForSingleObject(m_acceptthread_handle, 1000);
WaitForSingleObject() 函数的第一个参数指定了等待线程的句柄,第二个参数表示等待的时间,单位为毫秒。在等待了 1 秒钟之后,调用 GetExitCodeThread() 函数判断指定的线程是否结束,如果未结束,则调用 TerminateThread() 函数强行退出。

DWORD exitcode_thread = 0;
if (!GetExitCodeThread(m_acceptthread_handle, &exitcode_thread) || exitcode_thread == STILL_ACTIVE)
{
TerminateThread(m_acceptthread_handle, exitcode_thread);
}
CloseHandle(m_acceptthread_handle);
m_acceptthread_handle = NULL;
GetExitCodeThread() 函数的第一个参数表示指定线程的句柄;第二个参数是线程的退出码。如果指定的线程已经结束,则该函数的返回值是非零,如果线程未结束,则退出码 exitcode_thread 的值是 STILL_ACTIVE ,如果函数执行失败,则返回值为 0 。在将线程退出之后,将调用 CloseHandle() 函数关闭线程句柄,并且将线程句柄清空。

4.2 关闭监听连接的套接字

2.3.5 创建新线程接收数据”中提到,可以“优雅”关闭套接字,也可以“强行”关闭套接字。使用“优雅”的方式关闭套接字时,在调用closesocket()函数之前,需要调用shutdown()函数来禁止套接字的发送和接收动作。该函数的格式为

int shutdown(SOCKET s, int how);
其中,参数s 指定了要指定动作的套接字; how 表示禁止套接字的什么动作,该参数是 SD_RECEIVE 时,表示禁止套接字接收数据, SD_SEND 表示禁止套接字发送数据, SD_BOTH 表示进制套接字收发数据。

shutdown(m_socket_listen, SD_BOTH);
closesocket(m_socket_listen);
m_socket_listen = NULL;

4.3结束接收客户端数据的线程

用于接收客户端数据的线程句柄都保存在2.3.6 创建接收客户端数据的线程”中介绍的CTCPSocket_Server类的m_recvdata_threadhandle_array中。

for (int i = 0; i < MAX_CONNECTION; ++i)
{
if (m_clientconnectflag_array[i])
{
m_clientconnectflag_array[i] = false;
WaitForSingleObject(m_recvdata_threadhandle_array[i], 500);
if (!GetExitCodeThread(m_recvdata_threadhandle_array[i], &exitcode) || exitcode==STILL_ACTIVE)
{
TerminateThread(m_recvdata_threadhandle_array[i], exitcode);
}
CloseHandle(m_recvdata_threadhandle_array[i]);
m_recvdata_threadhandle_array[i] = NULL;
         .............
          }
   }
以上代码的作用是结束m_recvdata_threadhandle_array 中保存的句柄对应的线程。结束线程的方法与“ 4.1 结束接受客户端连接的线程”中提到的方法相同。

4.4 优雅关闭与客户端通信的套接字

在结束了接收客户端数据的线程之后,在4.3结束接收客户端数据的线程”中代码的for循环中,继续优雅关闭与客户端通信的套接字。优雅关闭套接字的方法与“4.2 关闭监听连接的套接字”中提到的方法相同。

shutdown(m_clientsocket_array[i], SD_BOTH);
closesocket(m_clientsocket_array[i]);
m_clientsocket_array[i] = NULL;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值