socket Unix: come inviare veramente grandi di dati con una sola “invia” chiamata?

StackOverflow https://stackoverflow.com/questions/1577825

  •  21-09-2019
  •  | 
  •  

Domanda

Sto usando unix scoket per il trasferimento dei dati (modalità SOCK_STREAM)

Ho bisogno di inviare una stringa di più di 100k caratteri. In primo luogo, io mando lunghezza di una stringa - è sizeof (int) byte.

length = strlen(s)
send(sd, length, sizeof(int))

Poi mando l'intera stringa

bytesSend = send(sd, s, length)

, ma per la mia sorpresa "bytesSend" è inferiore a "lunghezza".

Si noti che questo funziona bene quando io non mando così grandi stringhe. Può essere Esistono alcune limitazioni per la chiamata di sistema "invia", che mi mancava ...

È stato utile?

Soluzione

La chiamata di sistema send si suppone essere veloce , perché il programma potrebbe avere altre cose cose utili da fare. Certamente non si vuole attendere i dati da inviare fuori e l'altro computer per inviare una risposta -. Che avrebbe portato alla terribile rendimento

Quindi, tutto send realtà non fa altro che mette in coda alcuni dati per l'invio e restituisce il controllo al programma. Il kernel potrebbe copiare l'intero messaggio in memoria del kernel, ma questo sarebbe consumare un sacco di memoria del kernel (non buono).

Al contrario, il kernel code solo come gran parte del messaggio come è ragionevole. E 'responsabilità del programma di ri-tentativo di invio dei dati rimanenti.

Nel tuo caso, utilizzare un ciclo per inviare i dati che non ha ottenuto inviato la prima volta.

while(length > 0) {
    bytesSent = send(sd, s, length);
    if (bytesSent == 0)
        break; //socket probably closed
    else if (bytesSent < 0)
        break; //handle errors appropriately
    s += bytesSent;
    length -= bytesSent;
}

Al termine di ricezione sarà probabilmente bisogno di fare la stessa cosa.

Altri suggerimenti

La chiamata send() iniziale è sbagliata. È necessario passare send () l'indirizzo dei dati, vale a dire:.

bytesSend = send(sd, &length, sizeof(int))

Inoltre, questo si imbatte in alcuni rischi classici, con endianness, dimensione del int su varie piattaforme, eccetera.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top