[英]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的
CWinThread
和CAsyncSocket
新手,并尝试通过基于对话框的应用程序自己学习它们。
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.