Voglio essere in grado di chiamare recv()
senza dover bloccare, quindi voglio renderlo non bloccante, ma non voglio che non blocchi durante l'invio di dati. Quindi una presa può essere resa non bloccante solo per la funzione recv()
oppure la modalità di blocco/non blocco influisce su tutte le funzioni del socket?Un socket può essere reso non bloccante solo per la funzione recv()?
risposta
Non è possibile rendere il socket non bloccante solo per la funzione recv()
.
Tuttavia c'è qualcosa di simile (ma difettoso), che è utilizzando ioctlsocket()
con il flag FIONREAD
. Per esempio:
unsigned long l;
ioctlsocket(s, FIONREAD, &l);
Questa funzione restituisce (immediatamente senza bloccare) quanti byte è disponibile per essere letto, anche se non è abbastanza preciso (ma non ci preoccupiamo di questo, perché stiamo usando per sapere se ci sono dati da leggere e non sapere esattamente quanti byte ci sono).
Come ho già accennato in precedenza, questo approccio è viziata, perché non ti dice quando l'altra estremità è disconnesso, perché recv()
rendimenti 0
sulla disconnessione, e questa funzione ritornerà 0
se non sono disponibili dati!
Per Windows, è possibile utilizzare ioctlsocket()
per impostare il socket in modalità non bloccante. Sfortunatamente queste impostazioni si applicano a tutte le operazioni sul socket. Quindi per il tuo caso dovrai passare tra le ricezioni e le spedizioni.
Per la cronaca: Per Linux, si potrebbe avere usato la bandiera MSG_DONTWAIT
nelle recv()
argomenti di chiamata. La singola chiamata sarà quindi non bloccante.
Quale non è portatile in quanto non è una bandiera standard. Ad esempio, non è disponibile nella libreria winsock di Windows. –
@JoachimPileborg Sì! Colpa mia: non ho notato il tag di Windows. Ho modificato la mia risposta. – Christophe
Non posso farlo solo: 'unsigned long l; ioctlsocket (s, FIONREAD, &l); 'per vedere se ci sono dati da leggere? –
- 1. SQLAlchemy può essere configurato per essere non bloccante?
- 2. Linux, socket, connessione non bloccante
- 3. Un socket può essere chiuso da un altro thread quando una send/recv sullo stesso socket è attiva?
- 4. programmazione del socket udp non bloccante in C: cosa ottengo?
- 5. Connessione socket non bloccante su SSL?
- 6. C# socket non bloccante senza loop (vero)
- 7. Un puntatore a una funzione associata può essere utilizzato solo per chiamare la funzione
- 8. La funzione può essere richiamata solo nel thread principale, perché?
- 9. è sicuro recv() e send() su un socket contemporaneamente?
- 10. Gestione output di socket python recv
- 11. Se una recv non bloccante con MSG_PEEK ha esito positivo, verrà eseguita anche una successiva recv senza MSG_PEEK?
- 12. non bloccante presa, l'errore è sempre
- 13. select(), recv() e EWOULDBLOCK su socket non bloccanti
- 14. Impostazione del timeout per la funzione di recv
- 15. Autenticazione LDAP con `ldap-haskell`: può essere reso sicuro?
- 16. Un tipo dovrebbe essere solo in movimento, solo perché la copia può essere costosa?
- 17. Presa Java non bloccante
- 18. Connessione non bloccante
- 19. utilizzando una connessione socket non bloccante in C
- 20. jarsigner "Solo un alias può essere specificato"
- 21. Sotto Linux, può recv restituire sempre 0 su UDP?
- 22. java.lang.RuntimeException: Solo un Looper può essere creato per thread
- 23. può essere eseguito solo uwsgi con radice
- 24. sostituire il sistema() con funzione non bloccante
- 25. Scrapy: pausa non bloccante
- 26. Come è possibile avere un timeout di invio su un socket non bloccante?
- 27. Un ritorno UDP non bloccante può restituire con meno byte di quanto richiesto?
- 28. Un riferimento non può essere NULL o può essere NULL?
- 29. non bloccante getch()
- 30. Raccolta simultanea non bloccante?
È possibile utilizzare il flag 'MSG_PEEK' per vedere se c'è qualcosa da ricevere. Oppure usa per es. 'select' con un timeout zero. Tuttavia, per i socket TCP questi metodi funzionano solo per dire che c'è un leas * un * byte da ricevere, non si sa quanto è realmente disponibile. –
Sì, ma l'ultima volta che ho controllato recv() non bloccherà se c'è anche 1 byte di dati. – Joshua
@Joachim Pileborg Ma anche se avessi usato 'MSG_PEEK',' recv() 'avrebbe comunque bloccato. –