Wysyłanie i odbieranie danych PGM
Wysyłanie i odbieranie danych PGM jest podobne do wysyłania lub odbierania danych w dowolnym gniazdie. Istnieją zagadnienia specyficzne dla PGM, opisane w poniższych akapitach.
Wysyłanie danych PGM
Po utworzeniu sesji nadawcy PGM dane są wysyłane przy użyciu różnych funkcji wysyłania gniazd systemu Windows: send, sendto, WSASendi WSASendTo. Ponieważ dojścia Windows Sockets to dojścia systemu plików, inne funkcje, takie jak WriteFile oraz funkcje CRT, mogą również przesyłać dane. Poniższy fragment kodu ilustruje operację nadawcy PGM:
LONG error;
//:
error = send (s, pSendBuffer, SendLength, 0);
if (error == SOCKET_ERROR)
{
fprintf (stderr, "send() failed: Error = %d\n",
WSAGetLastError());
}
W przypadku korzystania z trybu komunikatów (SOCK_RDM) każde wywołanie funkcji send powoduje powstanie odrębnej wiadomości, co czasami nie jest pożądane; aplikacja może chcieć wysłać wiadomość o rozmiarze 2 megabajty za pomocą wielokrotnych wywołań do send. W takich okolicznościach nadawca może ustawić opcję gniazda RM_SET_MESSAGE_BOUNDARY, aby wskazać rozmiar komunikatu, który będzie przesyłany.
Jeśli okno wysyłania jest pełne, nowe wysłanie z aplikacji nie zostanie zaakceptowane, dopóki okno nie zostanie zaawansowane. Próba wysłania na gniazdo nieblokujące kończy się niepowodzeniem z elementem WSAEWOULDBLOCK; Gniazdo blokujące po prostu blokuje się do momentu, aż okno przechodzi do punktu, w którym żądane dane mogą być buforowane i wysyłane. W nakładających się operacjach we/wy operacja nie zostanie ukończona, dopóki okno nie zostanie wystarczająco zaawansowane, aby pomieścić nowe dane.
Odbieranie danych PGM
Po utworzeniu sesji odbiornika PGM dane są odbierane przy użyciu różnych funkcji odbioru gniazd systemu Windows: recv, recvfrom, WSARecvi WSARecvFrom. Ponieważ dojścia gniazd systemu Windows są również dojściami plików, funkcje ReadFile i CRT mogą również służyć do odbierania danych sesji PGM. System transportowy przekazuje dane do odbiornika, kiedy tylko dane są w sekwencji. Transport gwarantuje, że zwracane dane są ciągłe i wolne od duplikatów. Poniższy fragment kodu ilustruje operację odbierania PGM.
LONG BytesRead;
//:
BytesRead = recv (sockR, pTestBuffer, MaxBufferSize, 0);
if (BytesRead == 0)
{
fprintf(stdout, "Session was terminated\n");
}
else if (BytesRead == SOCKET_ERROR)
{
fprintf(stderr, "recv() failed: Error = %d\n",
WSAGetLastError());
}
W przypadku korzystania z trybu komunikatu (SOCK_RDM) transport wskazuje, kiedy zostanie odebrany komunikat częściowy z błędem WSAEMSGSIZE lub przez ustawienie flagi MSG_PARTIAL po powrocie z WSARecv i WSARecvFrom funkcji. Gdy ostatni fragment pełnego komunikatu jest zwracany do klienta, nie jest wskazywany błąd lub flaga.
Gdy sesja zostanie zakończona bezpiecznie, operacja odbierania kończy się niepowodzeniem z programem WSAEDISCON. W przypadku utraty danych w transporcie program PGM tymczasowo buforuje pakiety poza sekwencyjne i próbuje odzyskać utracone dane. Jeśli utrata danych jest nieodwracalna, operacja odbierania kończy się niepowodzeniem z usługą WSAECONNRESET, a sesja zostanie zakończona. Sesję można zresetować z powodu różnych warunków, w tym następujących:
- Odbiornik lub szybkość połączenia przychodzącego jest zbyt niska, aby nadążyć za szybkością danych przychodzących.
- Występuje nadmierna utrata danych, prawdopodobnie z powodu przejściowych warunków sieciowych, takich jak problemy z routingiem, niestabilność sieci itd.
- W nadawcy występuje nieodwracalny błąd.
- Nadmierne wykorzystanie zasobów występuje na komputerze lokalnym, na przykład przekroczenie maksymalnej dozwolonej pamięci wewnętrznej buforu lub napotkanie warunku braku zasobów.
- Występuje błąd sprawdzania spójności danych.
- Błąd w składniku PGM jest zależny od takich elementów jak TCP/IP lub Windows Sockets.
Zarówno pierwsza, jak i druga pozycja na powyższej liście mogą prowadzić do nadmiernego buforowania przez odbiorcę, zanim wyczerpane zostaną zasoby, lub zanim ostatecznie przekroczy okno nadawcy.
Kończenie sesji PGM
Nadawca lub odbiorca PGM może przestać wysyłać lub odbierać dane, wywołując closesocket. Odbiornik musi wywołać closesocket zarówno na gniazdach nasłuchiwania, jak i odbierania, aby zapobiec wyciekom uchwytu. Wywoływanie zamknięcia nadawcy przed wywołaniem zamknięcia gniazda gwarantuje, że wszystkie dane zostaną wysłane, i gwarantuje zachowanie danych naprawczych do momentu, aż okno wysyłania przejdzie poza ostatnią sekwencję danych, nawet jeśli aplikacja zakończy działanie.