Sockets: Server.exe stürzt einfach ab.



  • metapoint2011 schrieb:

    Was ist der Fehler?

    Dass du das in der Behandlung von WM_PAINT machst? Was soll das?



  • MFK schrieb:

    metapoint2011 schrieb:

    Was ist der Fehler?

    Dass du das in der Behandlung von WM_PAINT machst? Was soll das?

    naja wegen textout.

    hab mal versucht das in wm_command zu machen und alles über ein edit fenster auszugeben, doch dann stürzt das programm sofort ab.

    wo mach ich das eigentlich am besten?



  • metapoint2011 schrieb:

    wo mach ich das eigentlich am besten?

    Außerhalb des GUI-Threads.



  • MFK schrieb:

    metapoint2011 schrieb:

    wo mach ich das eigentlich am besten?

    Außerhalb des GUI-Threads.

    und wie geht das?



  • theta schrieb:

    Entweder lässt Du das Socket blockierend und lagerst das ganze auf einen eigenen Thread aus oder Du versetzt das Socket in den Non- Blocking Mode und programierst damit auf dem einen Thread.

    Gruss Sheldor



  • wie mach ich das auf einen anderen thread?

    kann mir einer ein kurzes beispiel geben?



  • Du erzeugst einen Thread mit CreateThread(...),
    und rufst dort deine Server Routinen auf.
    Während diese dort im Listen mode sind kann dein GUI Thread die Messages des windows handhaben,...

    greatz



  • okay ich habe jetzt neu angefangen und mal einen Client erstellt.

    Problem: Am Ende müsste eine MessageBox kommen die anzeigt ob man Verbunden ist
    oder nicht. Die kommt aber nicht.

    #include "winsock2.h"
    
    .....
    
    #pragma comment(lib, "Ws2_32.lib")
    int startWinsock(void);
    
    .....
    
    BOOL CALLBACK ClientSock(HWND, UINT, WPARAM, LPARAM);
    
    .....
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    
    	switch (message)
    	{
    
    	case WM_COMMAND:
    		break;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    BOOL CALLBACK ClientSock(HWND hWnd, UINT message, LPARAM lParam, WPARAM wParam)
    {
    	SOCKET s;
    	long rc;
    	SOCKADDR_IN addr;
    
    	switch (message)
    	{
    
    	case WM_COMMAND:
    
    		/////START WINSOCK
    			rc=startWinsock();
    			if(rc!=0)
    			{ MessageBox(hWnd, _T("Fehler: startWinsock"), _T("Fehler!"), MB_OK); return 1;}
    
    		/////Clientsocket erstellen
    			s=socket(AF_INET, SOCK_STREAM, 0);
    			if(s==INVALID_SOCKET)
    			{ MessageBox(hWnd, _T("ClientSocket nicht erstellt!"), _T("Fehler!"), MB_OK); return 1;}
    
    		/////Verbinden
    			memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten 
    			addr.sin_family=AF_INET;
    			addr.sin_port=htons(12345); // wir verwenden mal port 12345
    			addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener
    
    			rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
    			if(rc==SOCKET_ERROR)
    			{ MessageBox(hWnd, _T("Verbinden gescheitert!"), _T("Fehler!"), MB_OK); return 1;}
    			else
    			{ MessageBox(hWnd, _T("Verbunden!"), _T("Status"), MB_OK);}
    
    		break;
    	}
      return 0;
    }
    
    int startWinsock(void)
    {
    
      WSADATA wsa;
    
      return WSAStartup(MAKEWORD(2,0),&wsa);
    
    }
    


  • Ich habs mal auf diese Art hier gelöst.
    Ist aber nur nen ungefähres Beispiel, wie du es in die Threads einbauen solltest.
    Mußt wahrscheinlich noch ein wenig rumknobeln, damit es bei dir zum Laufen kommt.
    Das Problem war immer, wenn ich es in WinMain unterbrachte, dann wurde die MessageBearbeitung blockiert, und das Fenster blieb hängen.
    (So wie bei dir auch)
    Also lagerte ich das Listen zunächst in einen eigenen Thread aus.
    Dort wird dann auf ein Connect gewartet, die Hauptanwendung kann aber weiterhin ihre Messages abarbeiten.
    Kommt ein Connect zustande, dann startet der ListenThread einen ConnectThread, der die Kommunikation zwischen Server/Client durchführt.
    Ist alles vollbracht, und der Client loggt sich aus, dann wird auch der Connect Thread beendet und der ListenThread kann wieder gestartet werden.
    Denkbar ist hier auch, dass der Listen Thread MultiSocket-fähig gemacht wird, so daß er mehrere ConnectThread starten kann.
    Aber das müßtest du dir selbst austüfteln. (Dafür muss dem ConnectThread der Socket übergeben werden)

    Die grundlegende Technik ist diese:
    WinMain startet Listen Thread.
    WinMain arbeitet weiterhin Messages ab. (Kann auch welche vom ListenThread empfangen oder auch späer vom ConnectThread)
    ListenThread wartet auf Verbindungen.
    Verbindung trifft ein, es wird ein ConnectThread gestartet.
    ListenThread kann weitere ConnectThreads starten wenn weitere Verbindugen angefragt werden.
    ConnectThread bearbeitet den Datenaustauch Server/Client.
    ConnectThread wird nach Abschluß beendet.

    So im Groben.

    DWORD WINAPI Listen(LPVOID);
    DWORD WINAPI Connect(LPVOID);
    
    WinMain()
    {
    In WinMain rufst du dann CreateThread(NULL,0,Listen,(LPVOID)0,0,0); auf.
    }
    
    // Habe mal deinen ListenCode hier eingestellt, weiß nit, ob der auch wirklich läuft.
    DWORD WINAPI Listen(LPVOID)
    {
        SOCKET s;
        long rc;
        SOCKADDR_IN addr;
    
            /////START WINSOCK
                rc=startWinsock();
                if(rc!=0)
                { MessageBox(hWnd, _T("Fehler: startWinsock"), _T("Fehler!"), MB_OK); return 1;}
    
            /////Clientsocket erstellen
                s=socket(AF_INET, SOCK_STREAM, 0);
                if(s==INVALID_SOCKET)
                { MessageBox(hWnd, _T("ClientSocket nicht erstellt!"), _T("Fehler!"), MB_OK); return 1;}
    
            /////Verbinden
                memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten 
                addr.sin_family=AF_INET;
                addr.sin_port=htons(12345); // wir verwenden mal port 12345
                addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener
    
                rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
                if(rc==SOCKET_ERROR)
                { MessageBox(hWnd, _T("Verbinden gescheitert!"), _T("Fehler!"), MB_OK); return 1;}
                else
                { MessageBox(hWnd, _T("Verbunden!"), _T("Status"), MB_OK);
                  CreateThread(NULL, 0, Connect, (LPVOID)0, 0, 0);}
    
    }
    
    DWORD WINAPI Connect(LPVOID)
    {
    Hier die Server/Client Kommunikation, Datentransfer usw. unterbringen, ebenso, das Beenden der Verbindung und Aufräumen. 
    }
    

    Wie gesagt, mußt da noch ein wenig rumbasteln.

    Gruß,
    DC



  • alles kla. versuch ich morgen



  • was muss ich denn hinschreiben stadt hWnd? z.b bei ner message box?



  • Da du ja nur ein Fenster verwendest, und zwar das der Hauptanwendung musst du natürlich auch dessen hwnd benutzen.
    Man kann aber auch NULL eintragen, klappt auch.

    MessageBox(NULL, _T("Verbinden gescheitert!"), _T("Fehler!"), MB_OK);
    

    Gruß,
    DC



  • irgentwas stimmt nicht

    DWORD WINAPI Listen(LPVOID) 
    { 
        SOCKET s; 
        long rc; 
        SOCKADDR_IN addr; 
    
            /////START WINSOCK 
                rc=startWinsock(); 
                if(rc!=0) 
                { MessageBox(NULL, _T("Fehler: startWinsock"), _T("Fehler!"), MB_OK); return 1;} 
    
            /////Clientsocket erstellen 
                s=socket(AF_INET, SOCK_STREAM, 0); 
                if(s==INVALID_SOCKET) 
                { MessageBox(NULL, _T("ClientSocket nicht erstellt!"), _T("Fehler!"), MB_OK); return 1;} 
    
            /////Verbinden 
                memset(&addr,0,sizeof(SOCKADDR_IN)); 
                addr.sin_family=AF_INET; 
                addr.sin_port=htons(12345); 
                addr.sin_addr.s_addr=inet_addr("127.0.0.1"); 
    
                rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); 
                if(rc==SOCKET_ERROR) 
                { MessageBox(NULL, _T("Verbinden gescheitert!"), _T("Fehler!"), MB_OK); return 1;} 
                else 
                { MessageBox(NULL, _T("Verbunden!"), _T("Status"), MB_OK); 
    
    } 
    
    int startWinsock(void)
    {
    
      WSADATA wsa;
    
      return WSAStartup(MAKEWORD(2,0),&wsa);
    
    }
    

    1>f:\api_tutorial\clientsocket\clientsocket\clientsocket.cpp(169): error C2601: 'startWinsock': Lokale Funktionsdefinitionen sind unzulässig
    1> f:\api_tutorial\clientsocket\clientsocket\clientsocket.cpp(136): Diese Zeile enthält eine '{', die keine Entsprechung hat
    1>f:\api_tutorial\clientsocket\clientsocket\clientsocket.cpp(176): fatal error C1075: Dateiende erreicht, bevor das zugehörige Element für das linke Element Klammer "{" in "f:\api_tutorial\clientsocket\clientsocket\clientsocket.cpp(136)" gefunden wurde



  • metapoint2011 schrieb:

    1> f:\api_tutorial\clientsocket\clientsocket\clientsocket.cpp(136): Diese Zeile enthält eine '{', die keine Entsprechung hat

    Na dann schau doch mal, ob du für jede { auch eine } hast.



  • { MessageBox(NULL, _T("Verbunden!"), _T("Status"), MB_OK);
    

    Hier fehlt die Schließklammer }

    Und der andere Fehler zeigt dir an, daß du wohl startWinsock lokal definiert hast.
    Vielleicht auch kenen Prototypen am Anfang definiert?

    Gruß,
    DC



  • Don Carsto schrieb:

    Und der andere Fehler zeigt dir an, daß du wohl startWinsock lokal definiert hast.

    Das ist ein Folgefehler der fehlenden Klammer.



  • hab den definiert. jetzt hab ich die klammer gesetzt und fehler:

    "Listen": Nicht alle Steuerelementpfade geben einen Wert zurück.

    und es wird nix angezeigt



  • metapoint2011 schrieb:

    "Listen": Nicht alle Steuerelementpfade geben einen Wert zurück.

    Deine Funktion soll laut Deklaration ein DWORD zurückgeben. Tut sie aber nicht.

    metapoint2011 schrieb:

    und es wird nix angezeigt

    Dann steht das Programm wohl noch im connect.



  • MFK schrieb:

    metapoint2011 schrieb:

    "Listen": Nicht alle Steuerelementpfade geben einen Wert zurück.

    Deine Funktion soll laut Deklaration ein DWORD zurückgeben. Tut sie aber nicht.

    und wie mach ich das?

    metapoint2011 schrieb:

    und es wird nix angezeigt

    Dann steht das Programm wohl noch im connect.

    oh stimmt ja.



  • metapoint2011 schrieb:

    MFK schrieb:

    Deine Funktion soll laut Deklaration ein DWORD zurückgeben. Tut sie aber nicht.

    und wie mach ich das?

    Mit der return-Anweisung.


Anmelden zum Antworten