我是MFC的CWinThread
和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
是从CAsyncSocket
派生的类的对象,CSocketThread
派生自CWinThread
。
在线程头内,我添加了两行:
Public:
CConnectSoc threadSocket;
SOCKET threadHandleSocket;
在线程类.cpp中:
BOOL CSocketThread::InitInstance(){
threadSocket.Attach(threadHandleSocket);
return TRUE;
}
有人能告诉我接下来要做什么来向这些套接字发送数据吗?
答案 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);
}
这就是我所做的,到目前为止没问题......