Riepilogo

In questo articolo viene illustrata la differenza tra l'attributo I/O sovrapposto di un socket e la modalità di blocco o non di blocco del socket.

Ulteriori informazioni

Quando viene creato un socket, per impostazione predefinita è un socket di blocco. È possibile utilizzare il comando FIONBIO nella chiamata API ioctlsocket, WSAEventSelect o WSAAysncSelect per modificare il blocco della modalità socket a non bloccante. Se una chiamata Winsock non può essere completata immediatamente, la chiamata ha esito negativo e WSAGetLastError restituisce un errore WSAEWOULDBLOCK se si tratta di un socket non bloccante o la chiamata si blocca fino al completamento dell'operazione se si tratta di un socket di blocco. L'attributo I/O sovrapposto del socket è diverso dalla modalità di blocco o non di blocco del socket. Sebbene l'implementazione Winsock corrente richieda l'attributo I/O sovrapposto per la modalità socket non di blocco, sono concettualmente indipendenti e anche il relativo modello di programmazione è diverso. Per creare un socket con l'attributo di I/O sovrapposto, è possibile utilizzare l'API socket o l'API WSASocket con il flag WSA_FLAG_OVERLAPPED impostato. Se un'operazione di I/O sovrapposta non può essere completata immediatamente, la chiamata ha esito negativo e WSAGetLastError o GetLastError restituiscono WSA_IO_PENDING o ERROR_IO_PENDING, che in realtà è la stessa definizione di WSA_IO_PENDING. Per ulteriori informazioni, vedere il seguente articolo della Microsoft Knowledge Base:

179942 INFO: WSA_FLAG_OVERLAPPED è necessario per i socket non bloccantiSi noti che una volta creato un socket, non è possibile modificare l'attributo sovrapposto del socket. Tuttavia, è possibile chiamare l'API setsockopt con l'opzione SO_OPENTYPE su qualsiasi handle socket, incluso un INVALID_SOCKET, per modificare gli attributi sovrapposti per tutte le chiamate socket successive nello stesso thread. Il valore predefinito dell'opzione SO_OPENTYPE è 0, che imposta l'attributo sovrapposto. Tutti i valori di opzione diversi da zero rendono il socket sincrono e lo rendono in modo che non è possibile utilizzare una funzione di completamento. Impostando l'attributo di I/O sovrapposto di un socket, non significa che il socket eseguirà un'operazione di I/O sovrapposta. Ad esempio, se si specifica NULL sia per la funzione di completamento che per la struttura sovrapposta in WSARecv e WSASend oppure si chiama semplicemente le funzioni recv o send, questa verrà completata in modo di blocco. Per assicurarsi che l'I/O venga eseguito in modo sovrapposto, è necessario fornire una struttura sovrapposta nella funzione di I/O, a seconda della funzione utilizzata.

I/O sovrapposto

In Winsock 1, si crea un socket sovrapposto utilizzando l'API socket e utilizzare Win32 file I/O API ReadFile, ReadFileEx, WriteFile, WriteFileEx per eseguire i/o sovrapposti sull'handle del socket. In Winsock 2, si crea un socket sovrapposto utilizzando WSASocket con il flag WSA_FLAG_OVERLAPPED o semplicemente utilizzando l'API socket. È possibile utilizzare le API di I/O di file Win32 precedenti o WSASend, WSASendTo, WSARecv e WSARecvFrom precedenti per avviare un'operazione di I/O sovrapposta. Se si utilizza l'opzione SO_RCVBUF e SO_SNDBUF per impostare zero buffer di ricezione e invio dello stack TCP, in genere si indica allo stack TCP di eseguire direttamente i/o utilizzando il buffer fornito nella chiamata di I/O. Pertanto, oltre al vantaggio di sblocco dell'I/O socket sovrapposto, l'altro vantaggio è prestazioni migliori perché si salva una copia del buffer tra il buffer dello stack TCP e il buffer utente per ogni chiamata di I/O. Tuttavia, è necessario assicurarsi di non accedere al buffer utente dopo l'invio per l'operazione sovrapposta e prima del completamento dell'operazione sovrapposta. Per determinare se l'operazione di I/O sovrapposta è stata completata, è possibile utilizzare una delle seguenti opzioni:

  • È possibile fornire un handle di evento in una struttura sovrapposta utilizzata nella chiamata di I/O e attendere l'handle dell'evento per segnalare.

  • Utilizzare GetOverlappedResult o WSAGetOverlappedResult per eseguire il polling dello stato dell'operazione di I/O sovrapposta. In Windows NT, è possibile specificare NULL come handle di evento nella struttura sovrapposta. Tuttavia, in Windows 95 la struttura sovrapposta deve contenere un handle di evento di reimpostazione manuale. WSAGetOverlappedResult in Windows 98 e Windows Millennium Edition (ME) viene modificato in modo che si comporti come Windows NT e possa anche eseguire il polling dello stato di completamento con un handle di evento NULL nella struttura sovrapposta.

  • Utilizzare ReadFileEx, WriteFileEx, WSARecv, WSARecvFrom, WSASend o WSASendTo e scegliere di fornire una funzione di completamento da chiamare al completamento dell'operazione di I/O sovrapposta. Se si utilizza l'approccio della funzione di completamento, a un certo punto dopo aver emesso l'operazione di I/O sovrapposta è necessario emettere una funzione di attesa Win32 o una versione WSA della funzione di attesa per attendere un handle non segnalato per inserire il thread corrente in uno stato di attesa avvisabile. Quando l'operazione di I/O sovrapposta viene completata, viene chiamata la funzione di completamento, la funzione di attesa restituirà WAIT_IO_COMPLETION e il thread di attesa avvisabile si riattiva.

  • Utilizzare GetQueuedCompletionStatus e associare un socket, insieme al set di attributi I/O sovrapposto, a una porta di completamento I/O di Windows NT (IOCP). Con IOCP, non è necessario fornire una funzione di completamento, attendere un handle di evento per segnalare o eseguire il polling dello stato dell'operazione sovrapposta. Dopo aver creato IOCP e aggiunto l'handle del socket sovrapposto a IOCP, è possibile avviare l'operazione sovrapposta utilizzando una delle API di I/O menzionate in precedenza (ad eccezione di recv, recvfrom, send o sendto). Il thread di lavoro verrà bloccato nell'API GetQueuedCompletionStatus in attesa di un pacchetto di completamento I/O.You will have your worker thread block on GetQueuedCompletionStatus API waiting for an I/O completion packet. Quando un I/O sovrapposto viene completato, un pacchetto di completamento I/O arriva a IOCP e GetQueuedCompletionStatus restituisce. IOCP è il supporto del sistema operativo Windows NT per la scrittura di un server scalabile ad alta velocità effettiva utilizzando un threading molto semplice e codice di blocco nelle operazioni di I/O sovrapposte. Pertanto, l'utilizzo dell'I/O socket sovrapposto con i CIOCP di Windows NT può essere vantaggioso notevolmente in termini di prestazioni.

Modalità di blocco e non di blocco

Quando viene creato un socket, per impostazione predefinita è un socket di blocco. In modalità di blocco operazioni di I/O socket, connettere e accettare le operazioni tutte bloccate fino al completamento dell'operazione in questione. Per modificare la modalità di operazione socket dalla modalità di blocco alla modalità non di blocco, è possibile utilizzare WSAAsyncSelect, WSAEventSelect o il comando FIONBIO nella chiamata API ioctlsocket. WSAAsyncSelect esegue il mapping delle notifiche socket ai messaggi di Windows ed è il modello migliore per una singola applicazione GUI a thread. WSAEventSelect utilizza WSAEnumNetworkEvents per determinare la natura della notifica socket sull'evento di segnalazione ed esegue il mapping delle notifiche socket segnalando un evento. Si tratta di un modello utile per le applicazioni non GUI che non dispongono di un message pump, ad esempio un'applicazione di servizio di Windows NT. Il comando FIONBIO nella chiamata API ioctlsocket mette il socket in modalità non di blocco. Ma è necessario eseguire il polling dello stato del socket utilizzando l'API di selezione. Aggiornamento: l'impostazione di SO_RCVBUF su zero con recv sovrapposto non è necessaria per Windows 2000, che può copiare direttamente i dati nel buffer recv dell'applicazione. L'impostazione di SO_SNDBUF su zero con invio sovrapposto in Windows 2000 ha ancora lo stesso vantaggio di salvare una copia di memoria in Windows NT 4.0. È inoltre importante che l'applicazione emetta diversi messaggi sovrapposti in sospeso o recv se l'applicazione imposta il buffer dello stack corrispondente su 0.

Serve aiuto?

Amplia le tue competenze

Esplora i corsi di formazione >

Ottieni in anticipo le nuove caratteristiche

Partecipa a Microsoft Insider >

Queste informazioni sono risultate utili?

Come valuti la qualità della lingua?
Cosa ha influito sulla tua esperienza?

Grazie per il feedback!

×