Windows Sockets: jak działają gniazda z archiwamiWindows Sockets: How Sockets with Archives Work
W tym artykule wyjaśniono, jak obiekt CSocket , obiekt CSocketFile i obiekt CArchive są łączone w celu uproszczenia wysyłania i otrzymywania danych za pomocą gniazda systemu Windows.This article explains how a CSocket object, a CSocketFile object, and a CArchive object are combined to simplify sending and receiving data through a Windows Socket.
Artykuł Windows Sockets: przykład gniazd korzystających z archiwów prezentuje PacketSerialize
funkcję.The article Windows Sockets: Example of Sockets Using Archives presents the PacketSerialize
function. Obiekt archiwum w PacketSerialize
przykładzie działa podobnie jak obiekt archiwum przekazaną do funkcji serializacji MFC.The archive object in the PacketSerialize
example works much like an archive object passed to an MFC Serialize function. Istotną różnicą jest to, że w przypadku gniazd, archiwum jest dołączane do standardowego obiektu CFile (zwykle skojarzonego z plikiem dysku), ale do CSocketFile
obiektu.The essential difference is that for sockets, the archive is attached not to a standard CFile object (typically associated with a disk file) but to a CSocketFile
object. Zamiast nawiązywać połączenia z plikiem dysku, CSocketFile
obiekt nawiązuje połączenie z CSocket
obiektem.Rather than connecting to a disk file, the CSocketFile
object connects to a CSocket
object.
CArchive
Obiekt zarządza buforem.A CArchive
object manages a buffer. Gdy bufor przechowujący archiwum (wysyłanie) jest zapełniony, skojarzony CFile
obiekt zapisuje zawartość bufora.When the buffer of a storing (sending) archive is full, an associated CFile
object writes out the buffer's contents. Opróżnianie buforu archiwum dołączonego do gniazda jest równoznaczne z wysłaniem komunikatu.Flushing the buffer of an archive attached to a socket is equivalent to sending a message. Gdy bufor ładowania (otrzymywanie) jest zapełniony, CFile
obiekt przestaje czytać do momentu, gdy bufor będzie dostępny ponownie.When the buffer of a loading (receiving) archive is full, the CFile
object stops reading until the buffer is available again.
Klasa CSocketFile
pochodzi z CFile
, ale nie obsługuje funkcji składowych CFile , takich jak funkcje pozycjonowania ( Seek
, GetLength
, SetLength
, itd.), funkcje blokowania ( LockRange
, UnlockRange
) lub GetPosition
funkcji.Class CSocketFile
derives from CFile
, but it does not support CFile member functions such as the positioning functions (Seek
, GetLength
, SetLength
, and so on), the locking functions (LockRange
, UnlockRange
), or the GetPosition
function. Wszystkie obiekty CSocketFile muszą mieć sekwencję zapisu lub odczytu bajtów do lub z skojarzonego CSocket
obiektu.All the CSocketFile object must do is write or read sequences of bytes to or from the associated CSocket
object. Ponieważ plik nie jest uwzględniony, operacje takie jak Seek
i GetPosition
nie mają sensu.Because a file is not involved, operations such as Seek
and GetPosition
make no sense. CSocketFile
jest pochodną CFile
, więc zwykle dziedziczy wszystkie te funkcje elementów członkowskich.CSocketFile
is derived from CFile
, so it would normally inherit all of these member functions. Aby tego uniknąć, nieobsługiwane CFile
funkcje członkowskie są zastępowane w programie w CSocketFile
celu wygenerowania CNotSupportedException.To prevent this, the unsupported CFile
member functions are overridden in CSocketFile
to throw a CNotSupportedException.
CSocketFile
Obiekt wywołuje funkcje elementów członkowskich obiektu, CSocket
Aby wysyłać lub odbierać dane.The CSocketFile
object calls member functions of its CSocket
object to send or receive data.
Na poniższej ilustracji przedstawiono relacje między tymi obiektami po obu stronach komunikacji.The following figure shows the relationships among these objects on both sides of the communication.
CArchive, CSocketFile i CSocketCArchive, CSocketFile, and CSocket
Celem tej pozornej złożoności jest przełączenie Cię z konieczności zarządzania szczegółami gniazda.The purpose of this apparent complexity is to shield you from the necessity of managing the details of the socket yourself. 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.You create the socket, the file, and the archive, and then begin sending or receiving data by inserting it to the archive or extracting it from the archive. CArchive, CSocketFilei CSocket zarządzają szczegółami w tle.CArchive, CSocketFile, and CSocket manage the details behind the scenes.
CSocket
Obiekt jest w rzeczywistości obiektem dwustanowym: czasami asynchroniczny (zwykły stan) i czasami synchronicznie.A CSocket
object is actually a two-state object: sometimes asynchronous (the usual state) and sometimes synchronous. W stanie asynchronicznym gniazdo może odbierać asynchroniczne powiadomienia z platformy.In its asynchronous state, a socket can receive asynchronous notifications from the framework. Jednak podczas operacji, takiej jak otrzymywanie lub wysyłanie danych, gniazdo zostanie synchroniczne.However, during an operation such as receiving or sending data the socket becomes synchronous. Oznacza to, że gniazdo nie będzie otrzymywać powiadomień asynchronicznych, dopóki operacja synchroniczna nie zostanie ukończona.This means the socket will receive no further asynchronous notifications until the synchronous operation has completed. Ponieważ przełącza on tryby, można na przykład wykonać następujące czynności:Because it switches modes, you can, for example, do something like the following:
void CMySocket::OnReceive(int nErrorCode)
{
if (0 == nErrorCode)
{
CSocketFile file(this);
CArchive ar(&file, CArchive::load);
CString str;
ar >> str;
}
}
Jeśli CSocket
nie zostały zaimplementowane jako obiekt dwustanowy, może być możliwe otrzymywanie dodatkowych powiadomień dotyczących tego samego rodzaju zdarzenia podczas przetwarzania poprzedniego powiadomienia.If CSocket
were not implemented as a two-state object, it might be possible to receive additional notifications for the same kind of event while you were processing a previous notification. Na przykład użytkownik może otrzymać OnReceive
powiadomienie podczas przetwarzania OnReceive
.For example, you might get an OnReceive
notification while processing an OnReceive
. W powyższym fragmencie kodu wyodrębnianie str
z archiwum może prowadzić do rekursji.In the code fragment above, extracting str
from the archive might lead to recursion. Przełączanie Stanów CSocket
uniemożliwia rekursję, uniemożliwiając dodatkowe powiadomienia.By switching states, CSocket
prevents recursion by preventing additional notifications. Ogólna reguła nie dotyczy powiadomień w ramach powiadomień.The general rule is no notifications within notifications.
Uwaga
CSocketFile
Można również użyć jako pliku (z ograniczeniami) bez CArchive
obiektu.A CSocketFile
can also be used as a (limited) file without a CArchive
object. Domyślnie CSocketFile
parametr bArchiveCompatible konstruktora ma wartość true.By default, the CSocketFile
constructor's bArchiveCompatible parameter is TRUE. Określa, że obiekt pliku jest używany z archiwum.This specifies that the file object is for use with an archive. Aby użyć obiektu pliku bez archiwum, w parametrze bArchiveCompatible należy przekazać wartość false .To use the file object without an archive, pass FALSE in the bArchiveCompatible parameter.
W trybie "zgodne z archiwum" CSocketFile
obiekt zapewnia lepszą wydajność i zmniejsza zagrożenie "zakleszczenie".In its "archive compatible" mode, a CSocketFile
object provides better performance and reduces the danger of a "deadlock." Zakleszczenie występuje, gdy zarówno gniazdo wysyłające, jak i przejmujące czekają na siebie lub oczekują na wspólny zasób.A deadlock occurs when both the sending and receiving sockets are waiting on each other, or waiting for a common resource. Taka sytuacja może wystąpić, jeśli CArchive
obiekt działał w sposób, w CSocketFile
jaki działa, z CFile
obiektem.This situation might occur if the CArchive
object worked with the CSocketFile
the way it does with a CFile
object. W programie CFile
archiwum może założyć, że jeśli odbierze mniejszą liczbę bajtów niż zażądano, osiągnięto koniec pliku.With CFile
, the archive can assume that if it receives fewer bytes than it requested, the end of file has been reached. CSocketFile
Dane są jednak oparte na komunikatach; bufor może zawierać wiele komunikatów, więc otrzymanie mniejszej liczby bajtów nie oznacza końca pliku.With CSocketFile
, however, data is message based; the buffer can contain multiple messages, so receiving fewer than the number of bytes requested does not imply end of file. Aplikacja nie jest blokowana w tym przypadku, ponieważ może w tym przypadku CFile
, i może kontynuować odczytywanie komunikatów z bufora do momentu, gdy bufor jest pusty.The application does not block in this case as it might with CFile
, and it can continue reading messages from the buffer until the buffer is empty. Funkcja IsBufferEmpty w CArchive
jest przydatna do monitorowania stanu buforu Archiwum w takich przypadkach.The IsBufferEmpty function in CArchive
is useful for monitoring the state of the archive's buffer in such a case.
Aby uzyskać więcej informacji, zobacz Windows Sockets: używanie gniazd z archiwamiFor more information, see Windows Sockets: Using Sockets with Archives
Zobacz teżSee also
Windows Sockets w MFCWindows Sockets in MFC
CObject:: serializowaćCObject::Serialize