[SOCKETS] Windows bekommt keine definierte Socket notify Meldung



  • Hi Leute,

    ich arbeite grade an einem Chatprogramm um mich etwas mit den Winsocks außeinander zu setzen. Jetzt habe ich allerdings ein Prob:

    Wenn ich hiermit eine Nachricht definiere die Windows an mein Fenster senden soll

    WSAAsyncSelect(sock,hDlg,WM_SOCKET_NOTIFY,FD_CONNECT|FD_READ|FD_CLOSE);
    

    Und das natürlich auch noch definiere

    #define WM_SOCKET_NOTIFY (WM_USER + 1)
    

    müsste mein Programm doch in der Callbackschleife eine Messagebox ausgeben, wenn ich Daten empfange.
    Allerdings tut es das nicht, ich weiß aber zu 100%, dass Daten gesendet werden.

    Mein kompletter Code:

    #include <windows.h>
    #include <shlwapi.h>
    #include "resource.h"
    #define WM_SOCKET_NOTIFY (WM_USER + 1)
    
    WSADATA	WSAData;
    SOCKET sock; // Der hauptsocket, muss global sein!
    
    HWND hDlg;
    
    HWND hwnd_edit_ip;
    HWND hwnd_edit_port;
    HWND hwnd_cmd_verbinden;
    HWND hwnd_edit_verlauf;
    HWND hwnd_edit_eingabe;
    
    bool verbunden = 0;
    // Prototypen
    BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
    BOOL edit_addline(HWND hWnd, UINT uIndex, LPCTSTR lpText);
    void send_message(LPCTSTR textstring);
    bool verbinden(void);
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
    
    	 DialogBox(hInstance,"IDD_Start",NULL,DlgProc);
    
       MSG msg; 
     while (GetMessage (&msg, NULL, 0, 0))
              {
              TranslateMessage (&msg) ;
              DispatchMessage (&msg) ;
              }
         return msg.wParam ;
    }
    
    BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    switch(message)
    {
    	case WM_INITDIALOG:
    
    		hwnd_edit_ip = GetDlgItem(hDlg,IDC_IPADRESS);
    		hwnd_edit_port = GetDlgItem(hDlg,IDC_PORT);
    		hwnd_cmd_verbinden = GetDlgItem(hDlg,IDC_CONNECT);
    		hwnd_edit_verlauf = GetDlgItem(hDlg,IDC_VERLAUF);
    		hwnd_edit_eingabe = GetDlgItem(hDlg,IDC_EINGABE);
    
           	SendMessage(hwnd_edit_ip,WM_SETTEXT,0,(long)"192.168.0.2");
    		SendMessage(hwnd_edit_port,WM_SETTEXT,0,(long)"12345");
    
    		return TRUE;
    	break;
    
    	case WM_SOCKET_NOTIFY:
    		MessageBox(NULL,"Der Socket wird angesprochen!","Hinweis",MB_OK);
    		switch(LOWORD(lParam)) {
    		case FD_READ:
    			MessageBox(NULL,"Daten zum lesen bereit!","Hinweis",MB_OK);
    			break;
    		}
    	break;
    
    	case WM_COMMAND:
    		switch(LOWORD(wParam))
    		{
    		case CMD_CANCEL:
    			PostQuitMessage(0);
    			break;
    		case IDC_CONNECT:
    			verbinden();
    			break;
    
    		case IDC_SEND:
    			char nachricht[99];
    		SendMessage(hwnd_edit_eingabe,WM_GETTEXT,99,(long)nachricht);
    		SendMessage(hwnd_edit_eingabe,WM_SETTEXT,NULL,NULL);
    		send_message(nachricht);
    		edit_addline(hwnd_edit_verlauf,0,"Client: ");
    		edit_addline(hwnd_edit_verlauf,0,nachricht);
    		edit_addline(hwnd_edit_verlauf,0,"\r\n");
    
    			break;
    		}
    		break;
    
    	case WM_DESTROY :
             PostQuitMessage (0) ;
             break;
    
    }
    return FALSE;
    }
    
    bool verbinden(void) {
    
    	if (verbunden) { // Verbindung beenden
    	SendMessage(hwnd_cmd_verbinden,WM_SETTEXT,0,(long)"Verbindung herstellen");
    
    	closesocket(sock);
    	WSACleanup();
    	verbunden = 0;	
    	edit_addline(hwnd_edit_verlauf,0,"** Verbindung zum Server abgebrochen!\r\n");
    
    	} else { // Verbindung starten
    
    		// WErte abrufen (IP und Port)
    
    		char serverip[16];
    		SendMessage(hwnd_edit_ip,WM_GETTEXT,16,(long)serverip);
    		char port[6];
    		SendMessage(hwnd_edit_port,WM_GETTEXT,6,(long)port);
    		int serverport = StrToInt(port);	
    
    	// Socket erstellen
    
    	WSAStartup(MAKEWORD(2,0),&WSAData);
    
    	sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); // socket erstellen
    
    	sockaddr_in sa;
    	sa.sin_family = AF_INET;
    	sa.sin_port = htons(serverport);
    	sa.sin_addr.S_un.S_addr = inet_addr(serverip);
    
    	if(connect(sock,(SOCKADDR*)&sa,sizeof(sa))==SOCKET_ERROR){
    		MessageBox(0,"Es konnte keine Verbindung zum Server aufgebaut werden","Fehler",MB_OK | MB_ICONEXCLAMATION); return false;
    	} else { 
    	WSAAsyncSelect(sock,hDlg,WM_SOCKET_NOTIFY,FD_CONNECT|FD_READ|FD_CLOSE);
    
    	SendMessage(hwnd_cmd_verbinden,WM_SETTEXT,0,(long)"Verbindung schließen");
    	edit_addline(hwnd_edit_verlauf,0,"** Verbindung zum Server erfolgreich gestartet!\r\n");
    	verbunden = 1;
    
    }
    	} 
    
    	return true;
    }
    
    BOOL edit_addline(HWND hWnd, UINT uIndex, LPCTSTR lpText)
    {
    	uIndex = 100;
       DWORD dwSelStart = 0, dwSelEnd = 0;
       UINT  uLine, uNumChars = 0;
    
       SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwSelStart, (LPARAM)&dwSelEnd);
    
       for(uLine = 0; uLine < uIndex; uLine++)
          uNumChars += (UINT)(SendMessage(hWnd, EM_LINELENGTH, (WPARAM)uNumChars, 0) + 2);
    
       SendMessage(hWnd, EM_SETSEL, (WPARAM)uNumChars, (LPARAM)uNumChars);
       SendMessage(hWnd, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)lpText);
       SendMessage(hWnd, EM_SETSEL, (WPARAM)dwSelStart, (LPARAM)dwSelEnd);
    
       return(TRUE);
    }
    
    void send_message(LPCTSTR textstring) { // Mit dieser Funktion werden Nachrichten versendet
    
    send(sock,textstring,strlen(textstring),0);
    
    }
    

    MFG und hochachtungsvoll, Rodney



  • Ich kann keinen Fehler erkennen Rodney, ich mache das gleich wie Du und das funktioniert top...
    Vielleicht fehlen ein zwei breaks, bzw. schreibe das doch etwas schöner auf:

    case WM_SOCKET_NOTIFY:
    {
    	MessageBox(0, "Der Socket wird angesprochen!", "Hinweis", 0);
    	switch(lParam)
    	{
    		case FD_READ:
    		{
    			MessageBox(0, "Daten zum lesen bereit!", "Hinweis", 0);
    			break;
    		}
    		break;
    	}
    	break;
    }
    


  • hDlg wird nicht initialisiert!
    Scheiß globale Variablen...

    Die MessageLoop kannst du in diesem Fall weg lassen.

    Ein Dialog beendet man mit EndDialog() nicht mit PostQuitMessage()



  • Stimmt ja,
    schreib einfach oben statt HWND hDlg; --> HWND hMainDlg; und dann schreibe noch:

    BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    hMainDlg = hDlg;
    switch(message)
    {
    case WM_INITDIALOG:
    // ....

    Sollte gehen.



  • Da die Variable global ist, langt es sie in WM_INITDIALOG zu initialisieren und nicht bei jedem Aufruf von DlgProc.

    Man muss die globale Variable nicht umbenennen, man kann in DlgProc auch mit

    ::hDlg=hDlg;
    

    darauf zugreifen.



  • Hallo,

    D@niel $chumann schrieb:

    Man muss die globale Variable nicht umbenennen, man kann in DlgProc auch mit ´

    Code:
    ::hDlg=hDlg;

    darauf zugreifen.

    aber nur, wenn das ganze mit einem C++ - Compiler kompiliert wird 😉

    MfG


Anmelden zum Antworten