[nicht gelöst] Server mit select in MFC ?



  • hi,

    überlege gerade, wie ich eine Serveranwendung mit MFC basteln kann. Habe einen Dialog erstellt und will dann in einer Listbox die Nachrichten ausgeben, die ein Client geschickt hat.

    Ich habe bloß keine Ahnung, wie ich das genau realisieren soll, an welcher Stelle ich select aufrufe, vllt in OnInitDialog() ??, dann die Ausgabe der Nachrichten vom Client usw.

    Wäre super, wenn mir da jemand mal paar Vorschläge geben könnte und evtl. einen kleinen Code-Ausschnitt zum Demonstrieren !

    schonmal thx
    mfg



  • CAsyncSocket





  • ok super, vielen Dank !!



  • Ich muss doch nochmal schreiben, habe das doch etwas anders gelöst (mehr oder weniger):

    Ich habe mir ein MFC-Dialog erstellt, dadrauf dann eine Listbox gezogen, in der dann die empfangenen Nachrichten von den Clients angezeigt werden sollen, ich will ja einen select-Server.

    In OnInitDialog() erstelle ich einen Socket für den Client, dann eben den TCP-Server und dann noch einen Thread, der dauernd prüfen soll, ob neue Clients vorhanden sind und neue Nachrichten geschickt wurden (wie ich es schon mal beschrieben habe).
    Die Funktionen OpenTCPServer, InitSocket, Select, Accept, GetSocket, Receive und CloseSocket liegen in einer dll vor, die stimmen.

    Ich habe bloß noch Probleme mit dem Anzeigen der Nachricht und allgemein mit meinem 2. Thread.
    Der Code vom Server:

    // ServerDlg.cpp : Implementierungsdatei
    //
    
    #include "stdafx.h"
    #include "Server.h"
    #include "ServerDlg.h"
    
    ...
    
    // CServerDlg-Meldungshandler
    
    BOOL CServerDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Hinzufügen des Menübefehls "Info..." zum Systemmenü.
    
    	// IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		CString strAboutMenu;
    		strAboutMenu.LoadString(IDS_ABOUTBOX);
    		if (!strAboutMenu.IsEmpty())
    		{
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
    	//  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
    	SetIcon(m_hIcon, TRUE);			// Großes Symbol verwenden
    	SetIcon(m_hIcon, FALSE);		// Kleines Symbol verwenden
    
    	// TODO: Hier zusätzliche Initialisierung einfügen
    
    	acceptSock = socket(AF_INET, SOCK_STREAM, 0);
    	InitSocket();
    	serversock.OpenTCPServer("12000", "127.0.0.1");
    
    	pThread1 = AfxBeginThread(&ThreadProc, this);
    
    	return TRUE;  // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
    }
    
    ...
    
    void CServerDlg::OnClose()
    {
    	FD_CLR(acceptSock, &fdSock);
    	serversock.Close();
    	closesocket(acceptSock);
    	AfxEndThread(0);
    	CloseSocket();
    
    	CDialog::OnClose();
    }
    
    // Threadfunktion des worker-Threads
    UINT CServerDlg::ThreadProc(LPVOID lpArg)
    {
    	CServerDlg* dlg = (CServerDlg*) lpArg;
    	dlg->ThreadRun();
    	return 0;
    }
    
    void CServerDlg::ThreadRun()
    {
    	CWnd *pWnd = GetDlgItem(IDC_LIST1);
    	SOCKET clients[FD_SETSIZE];
    	int i;
    	for (i = 0; i < FD_SETSIZE; i++)
    	{
    		clients[i] = -1;
    	}
    
    	while (true)
    	{
    		FD_ZERO(&fdSock);
    		FD_SET(acceptSock, &fdSock);
    		for (i = 0; i < FD_SETSIZE; i++)
    		{
    			if (clients[i] != -1)
    			{
    				FD_SET(clients[i], &fdSock);
    			}
    		}
    		ergSelect = serversock.Select(fdSock);
    		if (ergSelect < 0)
    			pWnd->SetWindowTextA("Fehler in select");
    		if (FD_ISSET(acceptSock, &fdSock))
    		{
    			for (i = 0; i < FD_SETSIZE; i++)
    			{
    				if (clients[i] == -1)
    				{
    					serversock.Accept(clients[i]);
    					pWnd->SetWindowTextA("Neuer Client ist da...");
    					break;
    				}
    			}
    		}
    
    		for (i = 0; i < FD_SETSIZE; i++)
    		{
    			if (clients[i] == -1)
    				continue;			// kein verbundener Client an dieser Position im Array
    
    			if (FD_ISSET(clients[i], &fdSock))
    			{
    				ergSelect = serversock.Receive(buffer, sizeof(buffer));
    				if (ergSelect == 0 || ergSelect == -1)
    				{
    					pWnd->SetWindowTextA("Client hat Verbindung geschlossen");
    					closesocket(clients[i]);
    					FD_CLR(clients[i], &fdSock);
    					clients[i] = -1;
    				}
    				else
    				{
    					buffer[ergSelect] = '\0';
    					pWnd->SetWindowTextA(buffer);
    				}
    			}
    		}
    	}
    }
    

    Wäre schön, wenn mir nochmal jemand helfen könnte und vllt auch was zu diesem Code sagen könnte, irgendwas und irgendwo überseh ich was 🙂

    Schonmal thx !


Anmelden zum Antworten