Sdílet prostřednictvím


Windows Sockets: Jak pracují sokety s archivy

Tento článek vysvětluje, jak se objekt CSocket , CSocketFile a CArchive objekt kombinují, aby se zjednodušilo odesílání a přijímání dat prostřednictvím rozhraní Windows Socket.

Článek Windows Sockets: Příklad soketů používajících archivy představuje PacketSerialize funkci. Archivní objekt v příkladu PacketSerialize funguje podobně jako archivní objekt předaný do funkce serializace MFC. Zásadní rozdíl spočívá v tom, že u soketů není archiv připojen ke standardnímu objektu CFile (obvykle přidruženému k souboru disku), ale k objektu CSocketFile . Místo připojení k souboru CSocketFile disku se objekt připojí k objektu CSocket .

Objekt CArchive spravuje vyrovnávací paměť. Když je vyrovnávací paměť ukládání (odesílání) archivu plná, přidružený CFile objekt zapíše obsah vyrovnávací paměti. Vyprázdnění vyrovnávací paměti archivu připojeného k soketu odpovídá odeslání zprávy. Když je vyrovnávací paměť archivu načítání (příjmu) plná, objekt přestane číst, CFile dokud nebude vyrovnávací paměť opět k dispozici.

Třída CSocketFile je odvozena od CFile, ale nepodporuje CFile členské funkce, jako jsou funkce umístění (Seek, GetLength, SetLengthatd.), uzamykací funkce (LockRange, UnlockRange) nebo GetPosition funkce. Veškerý objekt CSocketFile musí provádět zápis nebo čtení posloupností bajtů do nebo z přidruženého CSocket objektu. Vzhledem k tomu, že se soubor nezabíná, operace, jako Seek jsou a GetPosition nemají smysl. CSocketFile je odvozen z CFile, takže by normálně dědit všechny tyto členské funkce. Chcete-li tomu zabránit, jsou nepodporované CFile členské funkce přepsány CSocketFile za účelem vyvolání CNotSupportedException.

Objekt CSocketFile volá členské funkce objektu CSocket k odesílání nebo přijímání dat.

Následující obrázek znázorňuje vztahy mezi těmito objekty na obou stranách komunikace.

CArchive, CSocketFile, and CSocket.
CArchive, CSocketFile a CSocket

Účelem této zjevné složitosti je chránit vás před nutností spravovat podrobnosti soketu sami. Vytvoříte soket, soubor a archiv a potom začnete odesílat nebo přijímat data tak, že je vložíte do archivu nebo ho extrahujete z archivu. CArchive, CSocketFile a CSocket spravují podrobnosti na pozadí.

Objekt CSocket je ve skutečnosti objekt se dvěma stavy: někdy asynchronní (obvyklý stav) a někdy synchronní. V asynchronním stavu může soket přijímat asynchronní oznámení z architektury. Během operace, jako je příjem nebo odesílání dat, se ale soket stane synchronní. To znamená, že soket nebude dostávat žádná další asynchronní oznámení, dokud synchronní operace nedokončila. Protože přepíná režimy, můžete například udělat něco podobného:

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

      ar >> str;
   }
}

Pokud CSocket nebyl implementován jako objekt se dvěma stavy, může být možné obdržet další oznámení pro stejný druh události během zpracování předchozího oznámení. Můžete například dostat OnReceive oznámení při zpracování OnReceive. V fragmentu kódu výše může extrakce str z archivu vést k rekurzi. Přepnutím stavů zabráníte rekurzi tím, CSocket že zabráníte dalším oznámením. Obecné pravidlo není v oznámeních žádné oznámení.

Poznámka

A CSocketFile lze také použít jako (omezený) soubor bez objektu CArchive . Ve výchozím nastavení CSocketFile je parametr bArchiveCompatible konstruktoru TRUE. Určuje, že se objekt souboru používá s archivem. Chcete-li použít objekt souboru bez archivu, předejte hodnotu FALSE v parametru bArchiveCompatible .

V režimu CSocketFile "kompatibilní s archivem" poskytuje objekt lepší výkon a snižuje nebezpečí "zablokování". K vzájemnému zablokování dochází v případě, že odesílající i přijímající sokety čekají na sebe nebo čekají na společný prostředek. K této situaci může dojít v případě, CArchive že objekt pracoval CSocketFile se způsobem, jakým objekt funguje s objektem CFile . V CFilepřípadě, že archiv může předpokládat, že pokud obdrží méně bajtů, než požaduje, byl dosažen konec souboru. Data CSocketFilejsou však založená na zprávách; vyrovnávací paměť může obsahovat více zpráv, takže příjem méně než požadovaný počet bajtů neznamená konec souboru. Aplikace v tomto případě neblokuje, protože může CFileobsahovat a může pokračovat ve čtení zpráv z vyrovnávací paměti, dokud nebude vyrovnávací paměť prázdná. Funkce IsBufferEmpty je CArchive užitečná pro monitorování stavu vyrovnávací paměti archivu v takovém případě.

Další informace naleznete v tématu Windows Sockets: Použití soketů s archivy

Viz také

Windows Sockets v prostředí MFC
Objekt CObject::Serializace