访问已传递给线程的套接字

时间:2016-05-08 10:21:57

标签: c++ multithreading mfc casyncsocket mfc-networking

我是MFC的CWinThreadCAsyncSocket的新手,并尝试使用基于对话框的应用程序自己学习它们。
以下是我想要做的事情: 制作服务器/多客户端模型:当客户端连接到服务器时,服务器将根据客户端数量创建线程并传递连接到线程的套接字。我已经通过这篇文章来做传递:https://support.microsoft.com/en-us/kb/175668

我已成功在每个连接上创建线程,但......
我的问题是:我是否可以从主窗口(GUI)重新访问已传递给线程的所有套接字发送(广播)数据到所有客户端?

这就是我传球的方式:
在服务器端:

void CMyServerDlg::OnAccept(){
CConnectSoc temp_soc;
m_Listener.Accept(temp_soc);
CSocketThread *pThr = (CSocketThread*)AfxBeginThread(
                                    RUNTIME_CLASS(CSocketThread),
                                    THREAD_PRIORITY_NORMAL,
                                    0,
                                    CREATE_SUSPENDED);
pThr->threadHandleSocket = temp_soc.Detach();
pThr->ResumeThread();
}


注意:m_Listener是从CAsyncSocket派生的类的对象,CSocketThread派生自CWinThread
在线程头内,我添加了两行:

Public:
CConnectSoc threadSocket;
SOCKET threadHandleSocket;

在线程类.cpp中:

BOOL CSocketThread::InitInstance(){

     threadSocket.Attach(threadHandleSocket);
     return TRUE;
}



有人能告诉我接下来要做什么来向这些套接字发送数据吗?

1 个答案:

答案 0 :(得分:0)

经过一番研究,我终于认为我可以回答我自己的问题,谢谢你的帮助;但请修理我,如果有更好的解决方案或我的不是一个好的做法。

我的解决方案:
这里的关键词是PostMessage()PostThreadMessage()。我们必须在GUI和线程之间进行通信。但是,问题是线程无法调用PostMessage() CWnd的成员函数来向GUI发送消息(我不知道为什么不这样做)。所以我需要一个线程类中的指针指向GUI中的CWnd:

在线程类的标题中:

public:
   CWnd *wParrent;

然后在创建线程的阶段,我只需添加1行:

void CMyServerDlg::OnAccept(){
   CConnectSoc temp_soc;
   m_Listener.Accept(temp_soc);
   CSocketThread *pThr = (CSocketThread*)AfxBeginThread(
                                RUNTIME_CLASS(CSocketThread),
                                THREAD_PRIORITY_NORMAL,
                                0,
                                CREATE_SUSPENDED);
   pThr->wParrent = this;  //<== this line
   pThr->threadHandleSocket = temp_soc.Detach();
   pThr->ResumeThread();
}

通过这样做,我现在可以从线程发布消息,为GUI提供我的线程ID。
在主题.cpp:

BOOL CSocketThread::InitInstance(){
   threadSocket.Attach(threadHandleSocket);
   wParrent->PostMessage(THREAD_STARTED, 0, (LPARAM)m_nThreadID);
   return TRUE;
}

然后在GUI:我们处理消息THREAD_STARTED,其中包含一个存储m_nThreadID以供将来使用的函数:
Dlg标题中的某处:

CDWordArray m_threadIDs;

Dlg .cpp

LRESULT CMyServer3Dlg::OnThreadStart(WPARAM, LPARAM lParam){
   DWORD ThreadID = (DWORD)lParam;
   m_threadIDs.Add(ThreadID);
   return 0;
}

向所有客户发送数据时,请在PostThreadMessage()循环中使用m_ThreadIDs

for (int i =0; i<m_threadIDs.GetCount(); ++i){
   PostThreadMessage(m_threadIDs[i],SEND_DATA,(WPARAM)bufferSize,(LPARAM)socketBuffer);
}

使用函数处理线程中的SEND_DATA消息以进行发送:
在主题.cpp:

void CSocketThread::SendDataFunc(WPARAM wParam, LPARAM lParam){
   ASSERT(threadSocket != NULL);
   if(threadSocket == NULL)
   {
       return;
   }
   else
   {
       char *socketBuffer = (char*)lParam;
       int bufferSize = (int)wParam;
       send(threadSocket, socketBuffer, bufferSize, 0);
   }

这就是我所做的,到目前为止没问题......