Mailslot Problem.



  • Hallo Ihr,

    ich habe die Idee eine Server-Client-Anwendung zu schreiben, bei der der Server ein x-beliebiger PC im LAN sein kann und es nie bekannt ist, welcher PC gerade als Server fungiert.
    Gelöst habe ich das Problem mit Mailslot. Der Client postet einfach eine Broadcast-Mail und wartet dann auf ein Echo. Erst dann wird die Verbindung via named Pipe hergestellt und Server-Client kommunizieren.

    Zuerst habe ich ein simples Szenario aufgebaut.
    Server:

    #include <windows.h>
    #include <iostream>
    
    HANDLE hSlot = NULL;
    HANDLE hSlotEvent = NULL;
    
    BOOL Makeslot() { 
        LPSTR lpszSlotName = "\\\\.\\mailslot\\Myw32Slot"; 
    
        hSlot = CreateMailslot(lpszSlotName, 0, MAILSLOT_WAIT_FOREVER, NULL);
        if (hSlot == INVALID_HANDLE_VALUE) return false;
    	std::cout << "CreateMailslot successful." << std::endl; 
        return true; 
    } 
    
    DWORD WINAPI MailSlotThread(void* lParam){
        DWORD cbMessage, cMessage, cbRead; 
        BOOL fResult; 
        char* lpszBuffer;
    	DWORD nRes = 0;
    
    	std::cout << "Thread startet ..." << std::endl;
        cbMessage = cMessage = cbRead = 0; 
        hSlotEvent = CreateEvent(NULL, true, false, NULL);
    
    	for(;;){
           fResult = GetMailslotInfo(hSlot, NULL, &cbMessage, &cMessage, NULL);              
           if (!fResult) return 1;
    
           if (cbMessage == MAILSLOT_NO_MESSAGE) {
    	       std::cout << "NO Message" << std::endl;
               nRes = WaitForSingleObject(hSlotEvent, 500);
    		   if(nRes != WAIT_TIMEOUT) break;
    	   } else {
              while(cMessage){
                 lpszBuffer = new char[cbMessage];
                 ReadFile(hSlot, lpszBuffer, cbMessage, &nRes, NULL);
    			 std::cout << lpszBuffer << std::endl;
    			 cMessage--;
    			 delete lpszBuffer;
    		  }
    	   }
    	}
        return 0;   
    }
    
    void main(){
    	DWORD hThread;
    	Makeslot();
    	hThread = (DWORD)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) MailSlotThread, 0, 0, NULL);
        MessageBox(NULL, "Ok", "stop here ...", 64);
    }
    

    Dann ein Client, der den Broadcast sendet:

    #include <windows.h>
    
    void WriteSlot(){ 
    	LPSTR lpszMessage = "Broadcast Slot - Message";  
        HANDLE hFile; 
        DWORD cbWritten; 
    
        hFile = CreateFile("\\\\*\\mailslot\\Myw32Slot", GENERIC_WRITE, 
                       FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
    
        if (hFile == INVALID_HANDLE_VALUE) return;
        WriteFile(hFile, lpszMessage, (DWORD) lstrlen(lpszMessage) + 1, &cbWritten, NULL); 
    } 
    
    void main(){
        WriteSlot();
    }
    

    Das funktioniert, mit einer Merkwürdigkeit:

    Test ich das auf meiner privaten Maschine, auf der vier LAN-Karten gemeinsam über einen Router laufen, kommen auf dem Server vier Meldungen an. An diesem LAN ist gar nichts besonderes. Ganz normals Home-NETWORK. Teste ich das auf einem anderen LAN, auf dem sich hunderte von PC herumlümmeln, kommt exakt eine Meldung (was es zu erwarten war == succesful) an.
    Der Server sollte schon klar unterscheiden können, wer andocken will, da eine unzahl von Clients geplant ist. Was läuft da schief?



  • Hallo,

    sry das ich das mal "hoch schiebe".
    Hat jemand mal den Code ausprobiert und hat ähnliches beobachtet?
    Wer ein kleines LAN um sich herum hat, bitte bitte ausprobieren 😉


Log in to reply