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
, SetLength
atd.), 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 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 CFile
případě, že archiv může předpokládat, že pokud obdrží méně bajtů, než požaduje, byl dosažen konec souboru. Data CSocketFile
jsou 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 CFile
obsahovat 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