0

我是 MFCCWinThread和的新手CAsyncSocket,并尝试通过基于对话框的应用程序自己学习它们。
这是我想要做 的:制作服务器/多客户端模型:当客户端数量连接到服务器时,服务器将根据客户端数量创建线程并通过套接字连接到线程。我已经参考了这篇文章来传递: 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是派生自CAsyncSocketCSocketThread派生自的类的对象CWinThread
在线程标题内,我添加了 2 行:

Public:
CConnectSoc threadSocket;
SOCKET threadHandleSocket;

在线程类 .cpp 中:

BOOL CSocketThread::InitInstance(){

     threadSocket.Attach(threadHandleSocket);
     return TRUE;
}



有人可以告诉我接下来要做什么将数据发送到这些套接字吗?

4

1 回答 1

1

经过一番研究,我终于想我可以回答我自己的问题了,谢谢你的帮助;但请修复我,如果有更好的解决方案或者我的不是一个好习惯。

我的解决方案:
这里的关键词是PostMessage()and 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;

下载.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);
   }

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

于 2016-05-10T06:32:24.987 回答