求助大神,线程结束问题。

张明奇-琦玉 2015-01-26 05:29:36
Socket通信
void EM_FileReceiving::Close()
{
m_bFileReceivingThread = FALSE;
closesocket(m_sListen);
BOOL bReuseaddr=TRUE;
setsockopt(m_sListen,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));//解除端口绑定
if (m_hThread != NULL)
{
TerminateThread(m_hThread, 0);//结束线程
m_hThread = NULL;
}

}

DWORD EM_FileReceiving::ListeningThread(LPVOID lParam)
{
//SOCKET sListen;
CEIM02Dlg *pDlg = (CEIM02Dlg *)lParam;
// Create our listening socket
pEm_fileReceiving->m_sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == pEm_fileReceiving->m_sListen)
{
MessageBox(0,"socket() failed:%d\n",0,0);
return 1;
}
// Select the local interface and bind to it

SOCKADDR_IN local;
local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(5150);

int ret = ::bind(pEm_fileReceiving->m_sListen, (PSOCKADDR)&local, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == ret)
{
MessageBox(0,"bind() failed:%d\n",0,0);
return 1;
}

listen(pEm_fileReceiving->m_sListen, 5);
int iAddress = sizeof(SOCKADDR_IN);
SOCKET sClient;
SOCKADDR_IN addrClient;
EnterCriticalSection(&pEm_fileReceiving->cs);
while( m_bFileReceivingThread )
{
if (!m_bFileReceivingThread)
{//为什么设置m_bFileReceivingThread为FALSE
break;
}
//这accpt还运行
sClient = accept(pEm_fileReceiving->m_sListen, (PSOCKADDR)&addrClient, &iAddress);
if (INVALID_SOCKET == sClient)
{
MessageBox(0,"accept() failed:%d\n", 0,0);
break;
}
char *szClientIP = new char [64];
strcpy(szClientIP, inet_ntoa(addrClient.sin_addr));
pDlg->PostMessage(WM_RECVFILE, (WPARAM)sClient, (LPARAM)szClientIP);
}
LeaveCriticalSection(&pEm_fileReceiving->cs);
return 1;
}
...全文
181 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
信阳毛尖 2015-01-28
  • 打赏
  • 举报
回复
引用 12 楼 l_andy 的回复:
在问大神们一个问题。用WaitForSingleObject(m_hThread,1000));能等待线程吗?? 我调试了怎么不返回 wait_timeOut 值,不知道,对不对,谢谢
可以,等1000ms,如果1000ms后等待的线程尚未激活(线程没跑完),就返回timeout,如果在这1000ms内等待的线程已激活(线程跑完),就返回WAIT_OBJECT_0
张明奇-琦玉 2015-01-28
  • 打赏
  • 举报
回复
在问大神们一个问题。用WaitForSingleObject(m_hThread,1000));能等待线程吗?? 我调试了怎么不返回 wait_timeOut 值,不知道,对不对,谢谢
昨夜无风 2015-01-28
  • 打赏
  • 举报
回复
是需要等待,但是关键是你很可能等待不到(也就是timeout),你等待不到的时候怎么结束?你现在是强制性结束,一般要求是线程返回自然结束。所以,等待不到的原因还是在阻塞式accept上,不用非阻塞,最起码用个select也是好的!
张明奇-琦玉 2015-01-27
  • 打赏
  • 举报
回复
引用 2 楼 mengfeihong 的回复:
没看到创建线程的代码。检查以下TerminateThread返回值吧,重点观察那几个m_变量的变化。
void EM_FileReceiving::Run(CWnd *pWnd) { InitializeCriticalSection(&cs); DWORD dwTID = 0; m_hThread = CreateThread(NULL, 0, ListeningThread, pWnd, 0, & dwTID); if (NULL == m_hThread) { MessageBox(0,"CreateThread() failed.",0,0); return; } CloseHandle(m_hThread); } 这是创建线程的代码。
张明奇-琦玉 2015-01-27
  • 打赏
  • 举报
回复
while( m_bFileReceivingThread ) { if (!m_bFileReceivingThread) { break; } sClient = accept(pEm_fileReceiving->m_sListen, (PSOCKADDR)&addrClient, &iAddress); //if (INVALID_SOCKET == sClient) //{ // //MessageBox(0,"accept() failed:%d\n", 0,0); // break; //}else //{ //} if(SOCKET_ERROR == sClient) { int res = WSAGetLastError(); if (WSAEWOULDBLOCK == res) { continue; } else { break; } }
oyljerry 2015-01-27
  • 打赏
  • 举报
回复
如果没有客户端请求,那么你的accept就一直在等待。
张明奇-琦玉 2015-01-27
  • 打赏
  • 举报
回复
引用 7 楼 lsq19871207 的回复:
问题的关键就是你使用阻塞sock模式,没有连接的情况下一直阻塞在accept函数中 你使用非阻塞sock模式就ok了

pEm_fileReceiving->m_sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   //要SOCKET_ERROR判断
unsigned long ulMod = 1;
ioctlsocket(pEm_fileReceiving->m_sListen,FIONBIO,&unMod);   //设置为非阻塞模式
while(m_bFileReceivingThread)
{
       sClient = accept(pEm_fileReceiving->m_sListen, (PSOCKADDR)&addrClient, &iAddress);
       if(sClient == INVALID_SOCKET || sClient == -1)
       {
              continue;
       }
       //接收、发送数据
       //........
       //........
}
if(!m_bFileReceivingThread)
       return 0;       //退出线程
//........
//........
我是在调用 BOOL bReuseaddr=TRUE; setsockopt(m_sListen,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));//解除端口绑定 之后accept才走INVALID_SOCKET的,而在正常阻塞的情况下,一致accpet返回的值为0。
张明奇-琦玉 2015-01-27
  • 打赏
  • 举报
回复
引用 5 楼 oyljerry 的回复:
随便你的代码修改了bFileReceivingThread,但是你的代码可能一直在accept等位置,没机会跑到if判断
我就想知道为什么没有机会执行if语句,用sleep也不可以。为什么???
信阳毛尖 2015-01-27
  • 打赏
  • 举报
回复
问题的关键就是你使用阻塞sock模式,没有连接的情况下一直阻塞在accept函数中 你使用非阻塞sock模式就ok了

pEm_fileReceiving->m_sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   //要SOCKET_ERROR判断
unsigned long ulMod = 1;
ioctlsocket(pEm_fileReceiving->m_sListen,FIONBIO,&unMod);   //设置为非阻塞模式
while(m_bFileReceivingThread)
{
       sClient = accept(pEm_fileReceiving->m_sListen, (PSOCKADDR)&addrClient, &iAddress);
       if(sClient == INVALID_SOCKET || sClient == -1)
       {
              continue;
       }
       //接收、发送数据
       //........
       //........
}
if(!m_bFileReceivingThread)
       return 0;       //退出线程
//........
//........
worldy 2015-01-27
  • 打赏
  • 举报
回复
TerminateThread(m_hThread, 0);//结束线程 一般不这样结束线程的, 线程如果没有死循环,则自动终止 线程如果有死循环,可以发送一个消息给线程,线程检测到终止信息,退出死循环
oyljerry 2015-01-27
  • 打赏
  • 举报
回复
随便你的代码修改了bFileReceivingThread,但是你的代码可能一直在accept等位置,没机会跑到if判断
信阳毛尖 2015-01-27
  • 打赏
  • 举报
回复
貌似你得把socket设置为非阻塞模式,毕竟你这个是server端啊
蒙飞鸿 2015-01-26
  • 打赏
  • 举报
回复
没看到创建线程的代码。检查以下TerminateThread返回值吧,重点观察那几个m_变量的变化。
张明奇-琦玉 2015-01-26
  • 打赏
  • 举报
回复
求助,为甚已经终止了线程。线程里的函数还运行。 而且m_bFileReceivingThread 已将设置为false了 但回调函数中的循环,还在运行 加sleep(1000);也不可以 waiforsingobject等待也不可以。求高手。谢谢

16,490

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧