Newsgroup: it.comp.programmare.win32
Titolo: Problema con le socket

Sto lavorando ad un programma che utilizza le socket per comunicare via rete
con un server. Tra i tanti messaggi che si scambiano client e server ce n'e'
uno particolarmente grande che a volte viene ricevuto completo a volte no.
Per questo motivo la funzione utilizzate per ricevere il messaggio ha al suo
interno un ciclo while che prosegue nella lettura finche' ci sono dati da
leggere.
Purtroppo io non sono in grado di determinare la dimensione del messaggio
che mi arrivera' per cui in pratica alloco un buffer sicuramente piu' grande
del messaggio e poi continuo la lettura finche' recv non mi ritorna 0. Il
problema e' che se sulla socket non ci sono dati da leggere la recv rimane
in uno stato indefinito e blocca il programma (penserei ad uno stato di
attesa, ma non c'e' timeout!).
Qualcuno sa da cosa potrebbe dipendere? In fondo al messaggio c'e' la
funzione di lettura e la modalita' con cui viene aperta la socket...
grazie e ciao
merlinO
===
sockServer = socket( AF_INET, SOCK_STREAM, 0 );
BOOL ReceiveBytes (unsigned char* pBuf, DWORD nSize, DWORD *nTotRead)
{
    unsigned char* pTemp = pBuf;
    int nRead = 0;
    int nRemaining = nSize;
    if ( pBuf == NULL || nSize == 0 )
    {
        assert( FALSE );
        return FALSE;
    }
    while ( nRemaining > 0 && nRead != 0 )
    {
        nRead = recv ( TCPIP_GetSocket(), pTemp, nRemaining, 0 );
        if (SOCKET_ERROR == nRead)
        {
            TRACE( _ERR, __ThisFunctionName__, "Receive failed: socket error
[%d]\n", WSAGetLastError( ) );
            assert( FALSE );
            return FALSE;
        }
        nRemaining -= nRead;
        pTemp += nRead;
    }
    *nTotRead = nSize - nRemaining;
    return TRUE;
}

 merlinO
Esiste la select() che ti permette di sapere se un socket è pronto per la
lettura.
Ciao. Federico.

 a écrit dans le message news:
agm790$ld$1...@e3k.asi.ansaldo.it...

Una domanda.
Visto che a priori la tua ReceiveBytes rimane in attesa finche' non riceve
il pacchetto completo e visto che in teoria il pacchetto potrebbe essere
lungo oppure un pezzo potrebbe non arrivare, per cui rimarrebbe in attesa
infinita, perche' non utilizzi un thread per fargli fare questo lavoro
invece che lasciarlo nel ciclo di programma principale che rimarrebbe
bloccato o al meno peggio rallenterebbe?
Scusa se non ho risposto alla tua domanda, ma non so i motivi per cui il
pacchetto potrebbe non essere ricevuto completo.
Ma almeno potresti evitare il bloccaggio del tuo programma.
Maurus

 Maurus
ciao e grazie
merlinO

 attesa, ma non c'e' timeout!).
La funzione recv() e' bloccante. Devi fare in modo che il socket aperto
divenga NON BLOCCANTE con questo pezzo di codice:
/***/
 unsigned long val = 1;
 ioctlsocket(tuosocket, FIONBIO, &val);
/***/
(attento, devi usarlo per OGNI socket che apri)
seconda di poi: non importa sapere quanto e' lunga l'informazione che ti
arriva. basta che tu sappia identificare la sua fine con un carattere
particolare (o qualsiasi altra cosa riconoscibile).
Fai ciclare la ricezione finche' non trovi il termine del messaggio che ti
serve: tieni presente che ci saranno dei caratteri in piu', nell'ultimo
messaggio, e saranno tutti impostati al valore di -58 (questo almeno mi
succede a me), quindi devi ripulire la stringa in ricezione e poi usarla
come meglio vuoi.
Joshi