其他线程如何正确关闭阻塞的Socket线程?
UINT DataRecvThreadProc(LPVOID lpParam)
{
C工具Dlg* aDlg = (C工具Dlg*)lpParam;//获取主对话窗的句柄!
int len;
CString str;
extern struct _TestNumRange TestNumRange;
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return 1;
}
int nPort = TestNumRange.PortID;;
CSocket aSocket;
CSocket serverSocket;
if (!aSocket.Socket())
{
AfxMessageBox(_T("创建套接字错误!"));
return 1;
}
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
aSocket.SetSockOpt(SO_REUSEADDR, (void *)&bOptVal, bOptLen, SOL_SOCKET);
if (!aSocket.Bind(nPort))
{
AfxMessageBox(_T("绑定端口失败!"));
return 1;
}
if (!aSocket.Listen(5))
{
AfxMessageBox(_T("监听失败!"));
return 1;
}
while (m_connect)
{
if (!aSocket.Accept(serverSocket))
{
continue;
}
else
{
unsigned char szRecvMsg[17412] = { 0 };
while (1)
{
len = serverSocket.Receive(szRecvMsg, 17412);
if (!m_connect) break;
if (len == 0 || len == -1)
{
m_connect = false; Recv_Signal = false;
if (Recv_Signal) break;
serverSocket.Close();
aSocket.Close();
aDlg->m_pThread = NULL; //在这里把指针NULL掉会不会出错?
AfxMessageBox(_T("探头掉线!"));
return 0;
}
if (Recv_Signal)
{
global_CriticalSection.Lock();
frashfifo = true;
signalFIFO.Input(szRecvMsg, len);
global_CriticalSection.Unlock();
}
}
serverSocket.Close();
}
}
aSocket.Close();
return 0;
}
在界面上有两个按钮,启动按钮就是开启这个工作线程,而结束按钮我是这样写的:
m_connect = false; Recv_Signal = false;
::WaitForSingleObject(m_pThread->m_hThread, 1000);
m_pThread = NULL;
return;
但是这样关闭的话,有一种情况会出错:
当工作线程阻塞在
len = serverSocket.Receive(szRecvMsg, 17412);
的时候,若我按下启动按钮而在这1000ms内Socket没有接收到新的信号,则工作线程无法关闭,而只是把指针NULL了。
当我再开启工作线程时,就会出现两个Socket监听同一个端口的情况,这就会导致严重的后果。。。
因此,我想知道在这样的情况下我要怎么实现UI去控制工作线程的开关。
注:在实际使用中,serverSocket.Receive会有几种接收的情况:5ms一个包,一分钟一个包,因此如果用CEvent的话,我不知道应该怎么设计才能保证不掉包的同时能实现对工作线程的开关控制。