简体   繁体   English

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

[英]Access a socket that has been passed to thread

I am new to MFC's CWinThread and CAsyncSocket , and trying to learn them myself with dialog based application. 我是MFC的CWinThreadCAsyncSocket新手,并尝试通过基于对话框的应用程序自己学习它们。
Here is what I want to do: make a server/multi-client model : when the number clients connect to server, the server will make threads according to the number of clients and passes the socket connecting to the thread. 这是我要执行的操作: 创建服务器/多客户端模型 :当多个客户端连接到服务器时,服务器将根据客户端的数量创建线程,并将套接字连接到该线程。 I have refereed this article to do the passing: https://support.microsoft.com/en-us/kb/175668 . 我已引用本文进行传递: https : //support.microsoft.com/zh-cn/kb/175668

I have successfully make thread on every connection, but... 我已经在每个连接上成功建立线程,但是...
My question is: Can I from the main windows(GUI) re-access all sockets that have been passed to threads to send (broadcast) data to all the clients? 我的问题是:我可以从主窗口(GUI)重新访问已传递给线程的所有套接字,以数据发送 (广播)到所有客户端吗?

This is how I do the passing: 这是我通过的方式:
On server side: 在服务器端:

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();
}


Note: m_Listener is the object of the class that derived from CAsyncSocket and CSocketThread is derived from CWinThread . 注意: m_Listener是从CAsyncSocket派生的类的对象,而CSocketThread是从CWinThread派生的。
Inside the thread header, I added 2 lines: 在线程标题内,我添加了两行:

Public:
CConnectSoc threadSocket;
SOCKET threadHandleSocket;

Inside the thread class .cpp: 在线程类.cpp中:

BOOL CSocketThread::InitInstance(){

     threadSocket.Attach(threadHandleSocket);
     return TRUE;
}



Can someone tell me what to do next to send data to those socket? 有人可以告诉我下一步如何将数据发送到那些套接字吗?

After some research, I finally think I can answer my own question, thanks for your help; 经过研究,我终于可以回答我自己的问题了,谢谢您的帮助; but please fix me, if there is a better solution or mine is not a good practice. 但是,如果有更好的解决方案,或者我的做法不是好的做法,请修复我。

MY SOLUTION: 我的解决方案:
The key word here is PostMessage() and PostThreadMessage() . 这里的关键词是PostMessage()PostThreadMessage() We must make the communication between the GUI and the Threads. 我们必须在GUI和线程之间进行通信。 However, the problem is the thread cannot call PostMessage() which is a member function of CWnd to send message to the GUI (I have no idea why not). 但是,问题是线程无法调用PostMessage()这是CWnd的成员函数)将消息发送到GUI(我不知道为什么不这样做)。 So I need a pointer in the thread class to point to the CWnd from the GUI: 因此,我需要线程类中的指针从GUI指向CWnd:

In header of the thread class: 在线程类的标题中:

public:
   CWnd *wParrent;

Then at the stage of creating thread, I just have to add 1 line: 然后在创建线程的阶段,我只需要添加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();
}

By doing this, I can now post message from the thread to give the GUI my thread's ID. 这样,我现在可以从线程中发布消息,以给GUI我线程的ID。
In the thread .cpp: 在线程.cpp中:

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

Then at GUI: we handle message THREAD_STARTED with a function to store m_nThreadID for future use: 然后在GUI:我们处理消息THREAD_STARTED并带有一个存储m_nThreadID以便将来使用的函数:
Somewhere in Dlg header: Dlg标头中的某处:

CDWordArray m_threadIDs;

Dlg .cpp Dlg .cpp

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

When sending data to all clients, use PostThreadMessage() in a loop through m_ThreadIDs : 向所有客户端发送数据时,请通过m_ThreadIDs在循环中使用PostThreadMessage()

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

Handle SEND_DATA message in the thread with a function to do the sending: 使用执行发送的函数处理线程中的SEND_DATA消息:
In thread .cpp: 在线程.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);
   }

That's what I have done, and no problem so far.... 那就是我所做的,到目前为止没有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM