Доступ к сокету, который был передан в поток

Я новичок в МФЦ 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,

Внутри заголовка темы я добавил 2 строки:

Public:
CConnectSoc threadSocket;
SOCKET threadHandleSocket;

Внутри класса потока .cpp:

BOOL CSocketThread::InitInstance(){

threadSocket.Attach(threadHandleSocket);
return TRUE;
}

Может кто-нибудь сказать мне, что делать дальше, чтобы отправить данные в эти сокеты?

0

Решение

После некоторого исследования я, наконец, думаю, что могу ответить на свой вопрос, спасибо за вашу помощь; но, пожалуйста, исправьте меня, если есть лучшее решение или мое не является хорошей практикой.

МОЕ РЕШЕНИЕ:

Ключевое слово здесь PostMessage() а также PostThreadMessage(), Мы должны установить связь между графическим интерфейсом и потоками. Однако проблема в том, что поток не может вызвать PostMessage() которая является функцией-членом CWnd отправить сообщение в графический интерфейс (я понятия не имею, почему нет). Поэтому мне нужен указатель в классе потока, чтобы указать на CWnd из GUI:

В заголовке класса потока:

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 идентификатор моей цепочки.

В теме .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);
}

Это то, что я сделал, и никаких проблем до сих пор ….

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]