next up previous contents
Next: Współpraca z Inetd Up: Programowe konfigurowanie sieci - Previous: O_NONBLOCK + sigaction()   Contents

Dane typu OOB

Każda para połączonych gniazd posiada logicznie wydzielony kanał komunikacyjny przeznaczony właśnie dla danych typu Out-Of-Band. Dane te nie są dostarczane procesowi podczas użycia zwykłych wywołań recv() - aby je odczytać musimy wyraźnie powiedzieć systemowi, że teraz chcemy obsłużyć OOB. Robi się to doając flagę MSG_OOB do wywołania recv():
  recv (s, buf, sizeof(buf), MSG_OOB);
  
To samo dotyczy wysyłania takich danych - musimy dodać tą samą flagę do wywołania send(). Innym sposobem na odczytywanie OOB jest umieszczenie ich w tym samym buforze, co zwykłe dane dzięki wywołaniu:
  int a = 1;
  setsockopt (s, SOL_SOCKET, SO_OOBINLINE, &a, sizeof(a))
  
Mimo wymieszania OOB z resztą danych nadal mamy możliwość stwierdzenia, czy odczytywane aktualnie dane są typu OOB, czy nie:
  int b=0;
  ioctl (s, SIOCATMARK, &b);
  
  printf ("Następne wywołanie recv() odczyta dane %s.\n", b == 1 ? "OOB" : "zwykłe");
  
Korzystamy tu z faktu, że system po odebraniu porcji danych OOB umieszcza je w osobnym buforze, a w zwykłym buforze gniazda umieszcza znak, że w danym miejscu znajdowały się (lub znajdują się - SO_OOBINLINE) dane OOB.

Do czego wykorzystuje się OOB ? Głównie do sygnalizowania zdalnemu procesowi jakichś szczególnych, priorytetowych żądań. Znajduje to zastosowanie np. w serwerach telnetd i rlogind. Załóżmy, że podczas sesji telnet wydaliśmy polecenie:

  $ cat bardzo\_duży\_plik
  
Po kilku linijkach widzimy, że niezupełnie o ten plik nam chodzilo. Co teraz ? Czy musimy długo czekać aż ten ogromny plik zostanie wyświetlony ? Otóż nie. Zazwyczaj wciskamy ctrl+c i po chwili mamy znowu dostęp do shella. Spróbujmy dla odmiany zamiast ctrl+c wpisać dowolne polecenie shella. Zauważymy, że nie zostało ono wykonane natychmiast - wykona się dopiero, kiedy polecenie cat wyświetli cały plik. Skąd więc ta różnica ? Właśnie w tym, że nasz klient telnetu wysyła pewne priorytetowe polecenia z włączoną flagą MSG_OOB. Z kolei serwer telnetu jest asynchronicznie informowany o nadejściu takich danych i w tym przypadku przerywa wszystkie inne czynności w celu ich obsłużenia. Na poziomie protokołu TCP dane OOB charakteryzują się tym, że są transmitowane w segmentach z włączoną flagą urgent (pilne) dzięki czemu są umieszczane w buforze gniazda przed wszystkimi innymi segmentami.

W przypadku danych OOB obsługiwanych przez protokół TCP trzeba pamiętać o dwóch ważnych rzeczach. Po pierwsze, jeśli w buforze znajduje się już porcja danych OOB i w tym czasie nadejdą kolejne takie dane to poprzednia porcja jest przesuwana do bufora przeznaczonego na zwykłe dane. Po drugie, protokół TCP umożliwia jednorazowe wysłanie tylko JEDNEGO BAJTU OOB.


next up previous contents
Next: Współpraca z Inetd Up: Programowe konfigurowanie sieci - Previous: O_NONBLOCK + sigaction()   Contents
Paweł Niewiadomski
2000-10-17