Udostępnij za pośrednictwem


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 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 CFileelementu , 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, and 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.

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 OnReceivemoż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 CFileprogramie archiwum można założyć, że jeśli otrzyma mniej bajtów niż zażądano, 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, ponieważ może CFilemieć 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)

Zobacz też

Gniazda systemu Windows w MFC
CObject::Serialize