WSAAsyncSelect() liefert falschen Wert



  • Hallo,

    Ich verwende in meiner Anwendung die Funktion WSAAsyncSelect() um das Blockieren
    von recv() und send() zu vermeiden.

    Im Buch von Herrn Petzold steht geschrieben, das der erste Aufruf von
    recv() damit gleich die Kontrolle wieder abgibt.
    Leider erhalte ich dadurch beim ersten Aufruf als Ergebnis 0FFFFFFFFh zurück,
    was aber nicht die Anzahl der empfangenen Bytes ist sonder der Fehler:
    WSAWOULDBLOCK, der bekanntlich ja keiner ist 👍

    Ich werde mittels Nachricht FD_READ darüber infomiert ob Daten bereitstehen.
    Wie kann ich nun recv() nutzen damit mir bei jedem Aufruf auch die Anzahl
    der gelesenen Bytes richig übergeben wird?

    .elseif uMsg == WM_SOCKET_NOTIFY
    		mov edx, lParam
    
    			.if dx == FD_CONNECT
    
    				invoke send, mysock, addr txtsenddata, sizeof txtsenddata, 0
    				ret
    			.endif
    
    			.if dx == FD_READ
    
    				invoke recv, mysock, addr txtinput, 256d, 0
    				add byteeingang, 256d
    			push byteeingang
    
    			        invoke CreateFile, addr dateiname, GENERIC_READ or GENERIC_WRITE, 0,NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
    				mov hdatei, eax
    				invoke SetFilePointer, hdatei, byteeingang, 0, FILE_BEGIN
    				invoke WriteFile, hdatei, addr txtinput, 256d, addr byteeingang, 0
    
    				Invoke CloseHandle, hdatei
    			pop byteeingang	
    				mov eax, byteeingang
    				call PRINT
    				invoke MessageBox, NULL, eax, addr szCaption, MB_OK
    				ret
    
    			.endif
    

    Im Moment arbeite ich noch mit festen Werten die aber nicht genau passen, da die Daten nicht immer so ankommen.

    Gruß, Nicky



  • Woher soll das Programm wissen, wie viele Bytes noch kommen? Du musst lesen, solange du lesen kannst!



  • Hab ich erst einmal benutzt aber ich fand das in meinem code:

    WORD wEvent = WSAGETSELECTEVENT(lParam);
    WORD wError = WSAGETSELECTERROR(lParam);
    if( wError && wError == WSAEWOULDBLOCK )
    ...
    


  • Jodocus schrieb:

    Woher soll das Programm wissen, wie viele Bytes noch kommen? Du musst lesen, solange du lesen kannst!

    Hallo zusammen,

    Was mir erst später eingefallen ist:
    Der Webserver trennt die Verbindung nachdem er seine Daten gesendet hat.
    Ich habe meinen Code folgendermaßen geändert:

    .elseif uMsg == WM_SOCKET_NOTIFY
    		mov edx, lParam
    
    			.if dx == FD_CONNECT
    
    				invoke send, mysock, addr txtsenddata, sizeof txtsenddata, 0
    
    			.endif
    
    			.if dx == FD_CLOSE
    
    				call sock_end
    
    				 mov eax, byteeingang
    				 call PRINT
    				 invoke MessageBox, NULL,eax, addr szCaption, MB_OK
    
    				mov ebx,byteeingang
    				sub ebx, 270d
    				mov esi, offset txtinput
    				add esi, 270d
    			push esi
    			push ebx
    				invoke CreateFile, addr dateiname, GENERIC_READ or GENERIC_WRITE, 0,NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
    				mov hdatei, eax
    			pop ebx
    			pop esi
    				invoke WriteFile, hdatei, esi, ebx, addr byteeingang, 0
    
    				invoke CloseHandle, hdatei
    
    			.endif
    
    			.if dx == FD_READ
    
    				mov esi, offset txtinput
    				mov ebx,byteeingang
    				add esi, ebx
    
    				invoke recv, mysock, esi, 1700d, 0
    				add byteeingang, eax
    
    			.endif
    

    Bei einem Connect wird mein Request an den Webserver gesendet (Anfrage Bilddatei).
    Sobald der Webserver mir das Bild schickt, laufen Daten ein und ich werden über
    FD_READ darüber informiert.
    In FD_READ werden die Daten der Reihenfolge in meinen Buffer übertragen, wofür
    die Variable byteeingang sorgt die die Daten mitzählt. Wenn 1000 Byte Daten
    eingegangen sind, überträgt der nächste Aufruf von recv() seine Daten ab der
    1000. Stelle im Buffer.

    Damit ich weiß wann keine Daten mehr kommen, habe ich das Schreiben der Daten
    in eine Datei in die Nachircht FD_CLOSE gepackt, da der Server die Verbindung
    dann trennt (s.o.)

    Da mir der Server zum Bild auch noch 270 Byte Response Text mitschickt,
    schreibe ich erst ab der 270. Stelle aus dem Puffer in die Datei und erhalte
    somit die reinen Bilddaten.

    Eine Frage habe ich aber noch.
    In Zeile 42 wird recv() aufgerufen und soll mir 1700 Byte Daten einlesen.
    Mein Programm funktioniert nur mit diesem Wert -+ 50.

    Ich nahm immer an das FD_READ sooft aufgerufen wird wie sich Daten im
    Windowspuffer befinden? Also währe es doch auch möglich z.B. nur 256 Byte einzulesen mit jedem Durchgang oder?

    Wenn ich den Wert aber auf 256 einstelle, liest er immer zu wenig ein, sodaß mein
    Bild nur halb oder zu einem Drittel angezeigt wird. Gibt es für das Einlesen
    einen "optimalen" Wert den man nehmen sollte?

    Ansonsten läuft es 👍

    Gruß Nicky



  • mov edx, lParam 
            .if dx == FD_CONNECT 
    
                ... ändert EDX 
    
            .endif 
    
            .if dx == FD_CLOSE 
    
    		    ... ändert EDX
    
            .endif 
    
            .if dx == FD_READ 
    
    			...
    
            .endif
    

Anmelden zum Antworten