Windows Sockets: funzionamento dei socket con archivi

Questo articolo illustra in che modo un oggetto CSocket , un oggetto CSocketFile e un oggetto CArchive vengono combinati per semplificare l'invio e la ricezione di dati tramite Windows Socket.

L'articolo Windows Sockets: Esempio di socket che usano archivi presenta la PacketSerialize funzione . L'oggetto archivio nell'esempio PacketSerialize funziona in modo molto simile a un oggetto archivio passato a una funzione Serialize MFC. La differenza essenziale è che per i socket, l'archivio è collegato non a un oggetto CFile standard (in genere associato a un file del disco) ma a un CSocketFile oggetto . Anziché connettersi a un file su disco, l'oggetto CSocketFile si connette a un CSocket oggetto .

Un CArchive oggetto gestisce un buffer. Quando il buffer di un archivio di archiviazione (invio) è pieno, un oggetto associato CFile scrive il contenuto del buffer. Lo scaricamento del buffer di un archivio collegato a un socket equivale all'invio di un messaggio. Quando il buffer di un archivio di caricamento (ricezione) è pieno, l'oggetto interrompe la CFile lettura fino a quando il buffer non è nuovamente disponibile.

La classe CSocketFile deriva da CFile, ma non supporta funzioni membro CFile , ad esempio le funzioni di posizionamento (Seek, GetLength, SetLengthe così via), le funzioni di blocco (LockRange, UnlockRange) o la GetPosition funzione . Tutti gli oggetti CSocketFile devono eseguire operazioni di scrittura o lettura di sequenze di byte da o verso l'oggetto associato CSocket . Poiché un file non è coinvolto, operazioni come Seek e GetPosition non hanno senso. CSocketFile è derivato da CFile, quindi normalmente erediterebbe tutte queste funzioni membro. Per evitare questo problema, le funzioni membro non supportate CFile vengono sottoposte a override in CSocketFile per generare un'eccezione CNotSupportedException.

L'oggetto CSocketFile chiama le funzioni membro del relativo CSocket oggetto per inviare o ricevere dati.

Nella figura seguente vengono illustrate le relazioni tra questi oggetti su entrambi i lati della comunicazione.

CArchive, CSocketFile, and CSocket.
CArchive, CSocketFile e CSocket

Lo scopo di questa apparente complessità è quello di proteggere voi stessi dalla necessità di gestire i dettagli del socket stesso. Creare il socket, il file e l'archivio e quindi iniziare a inviare o ricevere dati inserendolo nell'archivio o estrandolo dall'archivio. CArchive, CSocketFile e CSocket gestiscono i dettagli in background.

Un CSocket oggetto è in realtà un oggetto a due stati: a volte asincrono (lo stato consueto) e talvolta sincrono. Nello stato asincrono, un socket può ricevere notifiche asincrone dal framework. Tuttavia, durante un'operazione, ad esempio la ricezione o l'invio di dati, il socket diventa sincrono. Ciò significa che il socket non riceverà ulteriori notifiche asincrone fino al completamento dell'operazione sincrona. Poiché cambia modalità, è possibile, ad esempio, eseguire operazioni simili alle seguenti:

void CMySocket::OnReceive(int nErrorCode)
{
   if (0 == nErrorCode)
   {
      CSocketFile file(this);
      CArchive ar(&file, CArchive::load);
      CString str;

      ar >> str;
   }
}

Se CSocket non sono stati implementati come oggetto a due stati, potrebbe essere possibile ricevere notifiche aggiuntive per lo stesso tipo di evento durante l'elaborazione di una notifica precedente. Ad esempio, è possibile ricevere una OnReceive notifica durante l'elaborazione di un oggetto OnReceive. Nel frammento di codice precedente, l'estrazione str dall'archivio potrebbe comportare la ricorsione. Modificando gli stati, CSocket impedisce la ricorsione impedendo notifiche aggiuntive. La regola generale non è alcuna notifica all'interno delle notifiche.

Nota

Un CSocketFile oggetto può essere usato anche come file (limitato) senza un CArchive oggetto . Per impostazione predefinita, il CSocketFile parametro bArchiveCompatible del costruttore è TRUE. Specifica che l'oggetto file viene utilizzato con un archivio. Per usare l'oggetto file senza un archivio, passare FAL edizione Standard nel parametro bArchiveCompatible.

Nella modalità "compatibile con l'archivio", un CSocketFile oggetto offre prestazioni migliori e riduce il rischio di un "deadlock". Un deadlock si verifica quando entrambi i socket di invio e ricezione sono in attesa l'uno sull'altro o in attesa di una risorsa comune. Questa situazione può verificarsi se l'oggetto CArchive ha lavorato con il CSocketFile modo in cui funziona con un CFile oggetto . Con CFile, l'archivio può presupporre che, se riceve meno byte rispetto a quanto richiesto, è stata raggiunta la fine del file. Con CSocketFile, tuttavia, i dati sono basati su messaggi. Il buffer può contenere più messaggi, pertanto la ricezione di meno del numero di byte richiesti non implica la fine del file. L'applicazione non si blocca in questo caso come potrebbe con CFilee può continuare a leggere i messaggi dal buffer fino a quando il buffer non è vuoto. La funzione IsBufferEmpty in CArchive è utile per monitorare lo stato del buffer dell'archivio in questo caso.

Per altre informazioni, vedere Windows Sockets: Using Sockets with Archives (Uso di Socket con archivi)

Vedi anche

Windows Sockets in MFC
CObject::Serialize