2012-06-26 15 views
6

sto imparando a utilizzare SO_SNDTIMEO e SO_RCVTIMEO per controllare il timeout. È facile da usare con leggere socket. Ma quando voglio verificare timeout, restituisce sempre correttamente. Ecco quello che ho fatto: (tutti in modalità di blocco)come simulare un caso anomalo per la programmazione socket/tcp in linux, come terminare un lato della connessione?

  1. vicino il cliente leggere presa e uscire prima di server di avviare scrittura
  2. terminare il client prima di server iniziare scrittura
  3. scollegare il cavo di server dopo accetta ma prima di scrivere

beh, sembra che tutti questi casi scrivano appena restituiti con successo. Penso che la ragione dovrebbe essere che la porta è la risorsa gestita da os, e sul lato client, dopo che il programma è andato, la connessione TCP mostra ancora lo stato FIN_WAIT2.

quindi, non v'è alcun modo conveniente per simulare alcuni casi che scrittura può ricevere errori come EPIPE, EAGAIN?

risposta

5

Come ottenere l'errore EAGAIN?
Per ottenere l'errore EAGAIN, è necessario utilizzare socket non bloccanti. Con i socket non bloccanti, è necessario scrivere enormi quantità di dati (e smettere di ricevere dati sul lato peer), in modo che il buffer TCP interno venga riempito e restituisca questo errore.

Come ottenere l'errore EPIPE?
Per ottenere l'errore EPIPE, è necessario inviare grandi quantità di dati dopo aver chiuso il socket sul lato peer. È possibile ottenere maggiori informazioni sull'errore EPIPE da questo SO Link. Avevo fatto una domanda su Broken Pipe Error nel link fornito e la risposta accettata fornisce una spiegazione dettagliata. È importante notare che per ottenere l'errore EPIPE è necessario impostare il parametro flags di send su MSG_NOSIGNAL. Senza di ciò, una trasmissione anomala può generare un segnale SIGPIPE.

la nota
Si prega di notare che è difficile per simulare un errore di scrittura, come TCP memorizza generalmente i dati che si sta tentando di scrivere nella sua vita buffer interno. Pertanto, se il buffer interno dispone di spazio sufficiente, non verrà visualizzato immediatamente un errore. Il modo migliore è provare a scrivere enormi quantità di dati.È inoltre possibile provare a impostare una dimensione del buffer più piccola per l'invio utilizzando la funzione setsockopt con l'opzione SO_SNDBUF

+0

grazie per le vostre informazioni e avrò una prova. Per ** leggere **, ho effettivamente ottenuto EAGAIN e EWOULDBLOCK in modalità di blocco quando è scaduto. Presumo solo che funzioni allo stesso modo quando ** scrivi ** timeout. – xgwang

1

È possibile impostare la dimensione del buffer di ricezione in modo che sia veramente piccola su un lato e inviare un buffer di grandi dimensioni sull'altro. Oppure da un lato impostare il buffer di invio di piccole dimensioni e provare a inviare un messaggio di grandi dimensioni.

In caso contrario, il test più comune (credo) è quello di consentire al server e al client di parlare un po ', quindi rimuovere un cavo di rete.

5

È possibile simulare gli errori utilizzando fault injection. Ad esempio, libfiu è una libreria di errori che viene fornita con un progetto di esempio che consente di simulare errori dalle funzioni POSIX. Fondamentalmente usa LD_PRELOAD per iniettare un wrapper attorno alle normali chiamate di sistema (incluso write), e quindi il wrapper può essere configurato per passare alla chiamata di sistema reale, o restituire qualsiasi errore tu voglia.

+0

grazie. Probabilmente non è quello che sto cercando, ma l'iniezione di errori sembra interessante. Penso di poterlo imparare per migliorare la copertura del codice. – xgwang

Problemi correlati