VC++编程在线程中创建Sockets不响应消息问题

2008年02月20日 星期三 zmouse 1374次阅读

在工作中,我需要从CWinThread派生一个界面线程类,专门处理有关Windows套接字的一些相关操作,比如建立、连接、收发、关闭等。程序写完后,发现生成的CAsyncSocket实例不响应连接、接收等消息,百思不得其解。经过仔细跟踪调试,发现原来是我把CAsyncSocket实例过程写在了线程的InitInstance()函数里,而我又在此函数里进行循环等待事件,永远不从此函数返回,除非是要退出线程的时候才返回。见下面的错误代码:
BOOL CMyThread::InitInstance()
{
   // TODO: 在此执行任意逐线程初始化
   //创建属于线程的SOCKET*
   InitSocketAndBuf();
   HANDLE hEvents[3];
   hEvents[0] = m_hReConnectEvent; //连接事件
   SetEvent(hEvents[0]);//首先进行连接
   hEvents[1] = m_hRecvEvent;    //接收报文事件
   ResetEvent(hEvents[1]);
   hEvents[2] = m_hSendEvent;    //发送报文事件
   ResetEvent(hEvents[2]);

  while (1)
   {                
      DWORD dwWait = WaitForMultipleObjects(3,hEvents,FALSE,INFINITE);
      if (pApp->m_bExitFlag) break;
      switch (dwWait)
      {
      case WAIT_OBJECT_0: 
         ReConnectDevice();
         ResetEvent(hEvents[0]);
         break;
      case WAIT_OBJECT_0+1: 
         ResetEvent(hEvents[1]);
         break;
      case WAIT_OBJECT_0+2:
         ResetEvent(hEvents[2]);
         break;
      default:
         break;
      }
   }
   return FALSE;
}
InitSocketAndBuf()函数就是我实例化Sockets的过程。如果不从此InitInstance()函数返回true,系统控制权尚未交还,就不会继续运行线程的消息循环,因此阻塞了消息传递,所以Sockets的响应消息也就没有了,问题查到。

解决办法如下:

创建一新线程CNewThread,从CWinThread派生,此线程作为界面线程,在初始化函数InitInstance()里实例化Sockets和实例化CMyThread线程。CMyThread线程作为工作线程,在其初始化函数InitInstance()里进行事件等待。假如需要多个Sockets,可以实例化多个CMyThread线程,使得每个Sockets对应一个CMyThread线程实例。代码如下:
BOOL CNewThread::InitInstance()
{
   // TODO: 在此执行任意逐线程初始化
   //在InitMyThread()函数里实例化Sockets和实例化CMyThread线程*
   InitMyThread();

  return TRUE;
}

BOOL CMyThread::InitInstance()
{
   // TODO: 在此执行任意逐线程初始化
   HANDLE hEvents[3];
   hEvents[0] = m_hReConnectEvent; //连接事件
   SetEvent(hEvents[0]);//首先进行连接
   hEvents[1] = m_hRecvEvent;    //接收报文事件
   ResetEvent(hEvents[1]);
   hEvents[2] = m_hSendEvent;    //发送报文事件
   ResetEvent(hEvents[2]);
   while (1)
   {                
      DWORD dwWait = WaitForMultipleObjects(3,hEvents,FALSE,INFINITE);
      if (pApp->m_bExitFlag) break;
      switch (dwWait)
      {
      case WAIT_OBJECT_0: 
         ReConnectDevice();
         ResetEvent(hEvents[0]);
         break;
      case WAIT_OBJECT_0+1: 
         ResetEvent(hEvents[1]);
         break;
      case WAIT_OBJECT_0+2:
         ResetEvent(hEvents[2]);
         break;
      default:
         break;
      }
   }
   return FALSE;
}

项目归类于: 工作编程

发表您的评论

必填

必填、隐藏

必填 验证码图象

允许使用一些 HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

引用 (Trackback) 这篇文章  |  通过 RSS 聚合订阅评论


登录




请记住我

日历

2月 2008
« Jan   Mar »
 123
45678910
11121314151617
18192021222324
2526272829  

最新文章