Udostępnij przez


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 magazynującego (wysyłającego) jest pełny, skojarzony CFile obiekt zapisuje zawartość bufora. 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 CFileklasy , ale nie obsługuje funkcji składowych CFile , takich jak funkcje pozycjonowania (Seek, GetLength, SetLengthitd.), 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, więc normalnie dziedziczyłby wszystkie te funkcje składowe. Aby temu zapobiec, nieobsługiwane CFile funkcje składowe są przesłaniane w CSocketFile, aby spowodować wyrzucenie 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.
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.

Obiekt CSocket jest w rzeczywistości obiektem dwustanowym: zazwyczaj asynchronicznym, a czasami synchronicznym. W stanie asynchronicznym gniazdo może odbierać powiadomienia asynchroniczne z frameworku. 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 OnReceive może zostać wyświetlone powiadomienie OnReceive. 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. Zasadą ogólną jest brak powiadomień w ramach powiadomień.

Uwaga / Notatka

Obiekt CSocketFile może być również używany jako (ograniczony) plik bez CArchive obiektu. Domyślnie CSocketFile parametr bArchiveCompatible konstruktora ma wartość TRUE. Określa, że obiekt pliku jest używany z archiwum. Aby użyć obiektu pliku bez archiwum, podaj FALSE w parametrze bArchiveCompatible.

W trybie CSocketFile "zgodnym z archiwum" obiekt zapewnia lepszą wydajność i zmniejsza niebezpieczeństwo "zablokowania". Zablokowanie występuje, gdy zarówno gniazda wysyłające, jak i odbierające czekają na siebie nawzajem lub czekają na wspólny zasób. Taka sytuacja może wystąpić, jeśli obiekt CArchive działałby z CSocketFile w taki sposób, w jaki działa z obiektem CFile. W CFilearchiwum można założyć, że jeśli otrzyma mniej bajtów niż zażądano, to osiągnięto koniec pliku. Jednak dane CSocketFilesą 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, jak mogłaby to zrobić z CFile, 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)

Zobacz także

Windows Sockets w MFC
CObject::Serialize