Windows Sockets: jak działają gniazda z archiwami
W tym artykule wyjaśniono, jak obiekt CSocket , obiekt CSocketFile i obiekt CArchive są łączone w celu uproszczenia wysyłania i odbierania danych za pośrednictwem gniazda systemu Windows.
Artykuł Windows Sockets: Example of Sockets Using Archives (Gniazda systemu Windows: przykład gniazd korzystających z archiwów ) przedstawia PacketSerialize
funkcję . Obiekt archiwum w przykładzie PacketSerialize
działa podobnie jak obiekt archiwum przekazany do funkcji MFC Serialize . Istotną różnicą jest to, że w przypadku gniazd archiwum jest dołączone nie do standardowego obiektu CFile (zwykle skojarzonego z plikiem CSocketFile
dysku), ale do obiektu. Zamiast łączyć się z plikiem dysku, CSocketFile
obiekt łączy się z obiektem CSocket
.
Obiekt CArchive
zarządza buforem. Gdy bufor archiwum magazynu (wysyłania) jest pełny, skojarzony CFile
obiekt zapisuje zawartość buforu. Opróżnianie buforu archiwum dołączonego do gniazda jest równoważne wysyłaniu komunikatu. Gdy bufor ładowania (odbierania) archiwum jest zapełniony, CFile
obiekt przestaje odczytywać, dopóki bufor nie będzie ponownie dostępny.
Klasa CSocketFile
pochodzi z CFile
klasy , ale nie obsługuje funkcji składowych CFile , takich jak funkcje pozycjonowania (Seek
, GetLength
, SetLength
itd.), funkcje blokowania (LockRange
, UnlockRange
) lub GetPosition
funkcji. Cały obiekt CSocketFile musi wykonać operację zapisu lub odczytu sekwencji bajtów do lub ze skojarzonego CSocket
obiektu. Ponieważ plik nie jest zaangażowany, operacje takie jak Seek
i GetPosition
nie mają sensu. CSocketFile
pochodzi z CFile
elementu , więc zwykle dziedziczyłby wszystkie te funkcje składowe. Aby temu zapobiec, nieobsługiwane CFile
funkcje składowe są zastępowane w CSocketFile
celu wyrzucenia wyjątku CNotSupportedException.
Obiekt CSocketFile
wywołuje funkcje składowe obiektu CSocket
w celu wysyłania lub odbierania danych.
Na poniższej ilustracji przedstawiono relacje między tymi obiektami po obu stronach komunikacji.
CArchive, CSocketFile i CSocket
Celem tej pozornej złożoności jest ochrona przed koniecznością samodzielnego zarządzania szczegółami gniazda. Utworzysz gniazdo, plik i archiwum, a następnie zaczniesz wysyłać lub odbierać dane, wstawiając je do archiwum lub wyodrębniając je z archiwum. CArchive, CSocketFile i CSocket zarządzają szczegółami w tle.
CSocket
Obiekt jest w rzeczywistości obiektem dwustanowym: czasami asynchronicznym (zwykle stanem), a czasami synchronicznym. W stanie asynchronicznym gniazdo może odbierać powiadomienia asynchroniczne ze struktury. Jednak podczas operacji, takiej jak odbieranie lub wysyłanie danych, gniazdo staje się synchroniczne. Oznacza to, że gniazdo nie będzie otrzymywać dalszych powiadomień asynchronicznych do momentu zakończenia operacji synchronicznej. Ponieważ przełącza tryby, możesz na przykład zrobić coś podobnego do następującego:
void CMySocket::OnReceive(int nErrorCode)
{
if (0 == nErrorCode)
{
CSocketFile file(this);
CArchive ar(&file, CArchive::load);
CString str;
ar >> str;
}
}
Jeśli CSocket
obiekt nie został zaimplementowany jako obiekt dwustanowy, może być możliwe odbieranie dodatkowych powiadomień dla tego samego rodzaju zdarzenia podczas przetwarzania poprzedniego powiadomienia. Na przykład podczas przetwarzania elementu OnReceive
może zostać wyświetlone OnReceive
powiadomienie. W powyższym fragmentie kodu wyodrębnianie str
z archiwum może prowadzić do rekursji. Przełączając stany, CSocket
zapobiega rekursji, uniemożliwiając dodatkowe powiadomienia. Reguła ogólna nie jest powiadomieniami w ramach powiadomień.
Uwaga
Obiekt CSocketFile
może być również używany jako (ograniczony) plik bez CArchive
obiektu. Domyślnie parametr bArchiveCompatible konstruktora ma wartość TRUE.CSocketFile
Określa, że obiekt pliku jest używany z archiwum. Aby użyć obiektu pliku bez archiwum, przekaż wartość FALSE w parametrze bArchiveCompatible .
W trybie CSocketFile
"zgodnym z archiwum" obiekt zapewnia lepszą wydajność i zmniejsza niebezpieczeństwo "zakleszczenia". Zakleszczenie występuje, gdy zarówno gniazda wysyłające, jak i odbierające czekają na siebie nawzajem lub oczekują na wspólny zasób. Taka sytuacja może wystąpić, jeśli CArchive
obiekt pracował ze CSocketFile
sposobem, w jaki działa z obiektem CFile
. W CFile
programie archiwum można założyć, że jeśli otrzyma mniej bajtów niż zażądano, osiągnięto koniec pliku. Jednak dane CSocketFile
są oparte na komunikatach. Bufor może zawierać wiele komunikatów, więc odbieranie mniejszej liczby bajtów, których zażądano, nie oznacza zakończenia pliku. Aplikacja nie blokuje się w tym przypadku, ponieważ może CFile
mieć wartość , i może kontynuować odczytywanie komunikatów z buforu, dopóki bufor nie będzie pusty. Funkcja IsBufferEmpty w systemie CArchive
jest przydatna do monitorowania stanu buforu archiwum w takim przypadku.
Aby uzyskać więcej informacji, zobacz Windows Sockets: Using Sockets with Archives (Gniazda systemu Windows: używanie gniazd z archiwami)