Windows Sockets: blocco
In questo articolo e nei due articoli correlati vengono illustrati diversi problemi che si presentano nella programmazione Windows Sockets. Questo articolo descrive il blocco. Gli altri problemi sono trattati negli articoli: Windows Sockets: Ordinamento byte e Windows Sockets: conversione di stringhe.
Se si usa o si deriva dalla classe CAsyncSocket, sarà necessario gestire manualmente questi problemi. Se si usa o si deriva dalla classe CSocket, MFC li gestisce automaticamente.
Processi bloccati
Un socket può essere in "modalità di blocco" o "modalità non bloccante". Le funzioni dei socket in modalità di blocco (o sincrona) non restituiscono finché non possono completare l'azione. Si parla in questo caso di blocco perché il socket, la cui funzione è stata chiamata, non può eseguire alcuna operazione (è bloccato) finché la chiamata non restituisce il risultato. Una chiamata alla Receive
funzione membro, ad esempio, potrebbe richiedere un tempo arbitrario di completamento perché attende l'invio dell'applicazione (in questo caso se si usa CSocket
o si usa CAsyncSocket
con blocco). Se un CAsyncSocket
oggetto è in modalità non bloccante (in modo asincrono), la chiamata restituisce immediatamente e il codice di errore corrente, recuperabile con la funzione membro GetLastError , è WSAEWOULDBLOCK, che indica che la chiamata avrebbe bloccato non avrebbe restituito immediatamente a causa della modalità. (CSocket
non restituisce mai WSAEWOULDBLOCK. La classe gestisce automaticamente il blocco.
Il comportamento dei socket è diverso nei sistemi operativi a 32 e a 64 bit (quali Windows 95 o Windows 98) rispetto ai sistemi operativi a 16 bit (quali Windows 3.1). A differenza dei sistemi operativi a 16 bit, i sistemi operativi a 32 e a 64 bit utilizzano il multitasking di tipo preemptive e forniscono il multithreading. Nei sistemi operativi a 32 e a 64 bit è possibile inserire i socket in thread di lavoro distinti. Un socket in un thread può bloccarsi senza interferire con le altre attività dell'applicazione e senza impiegare il tempo di calcolo nel blocco. Per informazioni sulla programmazione multithreading, vedere l'articolo Multithreading.
Nota
Nelle applicazioni multithreading è possibile utilizzare la natura del blocco di CSocket
per semplificare la progettazione del programma senza influenzare la velocità di risposta dell'interfaccia utente. Gestendo le interazioni utente nel thread principale e l'elaborazione di CSocket
in thread differenti, è possibile separare queste operazioni logiche. In un'applicazione che non è multithreading, queste due attività devono essere combinate e gestite come un singolo thread, che in genere significa utilizzare CAsyncSocket
in modo da poter gestire le richieste di comunicazione su richiesta oppure eseguire l'override di CSocket::OnMessagePending
per gestire le azioni dell'utente durante un'attività sincrona di lunga durata.
Il resto di questa discussione è rivolto ai programmatori che utilizzano sistemi operativi a 16 bit:
In genere, se si utilizza CAsyncSocket
, è consigliabile eseguire operazioni asincrone anziché utilizzare operazioni di blocco. Nelle operazioni asincrone, dal punto in cui si riceve un codice di errore WSAEWOULDBLOCK dopo aver chiamato Receive
, ad esempio, attendere che la OnReceive
funzione membro venga chiamata per notificare che è possibile leggere di nuovo. Le chiamate asincrone vengono effettuate chiamando la funzione di notifica di callback appropriata del socket, ad esempio OnReceive.
In Windows, le chiamate di blocco sono considerate pratiche non corrette. Per impostazione predefinita, CAsyncSocket supporta le chiamate asincrone ed è necessario gestire il blocco manualmente usando le notifiche di callback. La classe CSocket, d'altra parte, è sincrona. Immette i messaggi di Windows e gestisce il blocco automaticamente.
Per ulteriori informazioni sul blocco, vedere la specifica di Windows Sockets. Per altre informazioni sulle funzioni "On", vedere Windows Sockets: Socket Notifications and Windows Sockets: Derivazione da classi socket.
Per altre informazioni, vedere: