2016-05-08 8 views
0

Ich bin neu in MFC CWinThread und CAsyncSocket, und versuchen, sie selbst mit dialogbasierter Anwendung zu lernen. Hier
ist das, was ich tun möchte:machen einen Server/Multi-Client-Modell: Wenn die Anzahl Clients mit dem Server verbinden, wird der Server-Threads machen nach der Anzahl der Clients und übergibt die Buchse an der Verbindungs Faden. Ich habe diesen Artikel um das Passing verwiesen: https://support.microsoft.com/en-us/kb/175668.

Ich habe erfolgreich Thread für jede Verbindung, aber ...
Meine Frage ist: Kann ich von den Hauptfenster (GUI) wieder Zugriff auf alle Steckdosen, die Fäden zu send bestanden, (Broadcast) Daten an alle Kunden?

Dies ist, wie ich das Passieren tun:
Auf Server-Seite:Zugriff auf einen Socket, der an Thread übergeben wurde

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


Hinweis: m_Listener ist das Objekt der Klasse, die aus CWinThread abgeleitet von CAsyncSocket und CSocketThread abgeleitet wird.
Innerhalb des Themas Header hinzugefügt I 2 Zeilen:

Public: 
CConnectSoc threadSocket; 
SOCKET threadHandleSocket; 

Innerhalb der Thread-Klasse CPP:

BOOL CSocketThread::InitInstance(){ 

    threadSocket.Attach(threadHandleSocket); 
    return TRUE; 
} 



Kann mir jemand sagen, was als nächstes tun schicken Daten an diese Steckdose?

+0

Po st Nachricht an den Thread mit [PostThreadMessage] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946%28v=vs.85%29.aspx). Um die Nachrichten von Threads an die Haupt-GUI zu posten verwenden Sie die normale 'PostMessage()' – cha

+0

@cha Vielen Dank für Ihren Kommentar, ich habe eine Recherche und 'PostThreadMessage()' erfordern m_hthreadID. Also denke ich, wir müssen 'PostMessage()' aus dem Thread zuerst, um diese ID zu bekommen. Und speichern Sie sie in einem Array irgendwo für die Haupt-GUI kann eine Schleife von 'PostThreadMessage()' tun? ist das, was ich tun muss? –

+0

'AfxBeginThread' gibt einen Zeiger auf ein 'CWinThread'-Objekt zurück, das eine Mitgliedsfunktion' PostThreadMessage' aufweist. Sie müssen nur den Zeiger speichern, der von 'AfxBeginThread' zurückgegeben wird. –

Antwort

0

Nach einigen Recherchen denke ich endlich, dass ich meine eigene Frage beantworten kann, danke für Ihre Hilfe; aber bitte repariere mich, ob es eine bessere Lösung gibt oder meine ist keine gute Praxis.

Meine Lösung:
Das Schlüsselwort hier ist PostMessage() und PostThreadMessage(). Wir müssen die Kommunikation zwischen der GUI und den Threads vornehmen. Das Problem ist jedoch der Thread kann nicht PostMessage() aufrufen, die eine Mitgliedsfunktion von CWnd ist, um eine Nachricht an die GUI zu senden (ich habe keine Ahnung, warum nicht). Also brauche ich einen Zeiger in der Thread-Klasse auf die CWnd von der GUI Punkt:

In Header der Thread-Klasse:

public: 
    CWnd *wParrent; 

Dann auf der Bühne Faden zu schaffen, ich habe gerade habe 1 Zeile hinzufügen:

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

auf diese Weise kann ich jetzt Nachricht aus dem Thread posten der GUI mein Thread ID zu geben.
Im Thread.cav:

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

dann bei GUI: Wir behandeln Nachricht THREAD_STARTED mit einer Funktion m_nThreadID für die zukünftige Verwendung zu speichern:
Irgendwo in Dlg-Header:

CDWordArray m_threadIDs; 

Dlg CPP

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

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

Handle SEND_DATA Nachricht mit einer Funktion in dem Gewinde:
In Gewinde CPP:

Wenn Daten an alle Clients senden, verwenden PostThreadMessage() in einer Schleife durch m_ThreadIDs

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

das ist, was ich getan habe, und kein Problem weit so ....