Być może wypróbowałeś wiele funkcji C, wiele funkcji biblioteki POSIX C i funkcji C opartych na UNIX w swoich programach. Większość funkcji C związanych z POSIX lub sieciami wykorzystuje niektóre flagi w ich nawiasie jako argument lub używana do określonych celów. Czy kiedykolwiek próbowałeś nauczyć się wbudowanych flag podczas programowania? Jeśli nie, jest całkowicie w porządku.
W tym artykule omówimy użycie flagi SO_ReuseADDR C. Jest to flaga typu logicznego całkowitego, która określa, czy ponowne użycie adresu lokalnego powinno być dozwolone przez reguły użyte do weryfikacji adresów podanych w wywołań systemu wiązania. Oznacza to, że gniazdo może wiązać się dla gniazd AF_INET, z wyjątkiem obecności aktywnego gniazda słuchania podłączonego do adresu. Nie jest możliwe wiązanie się z portem określonym gniazdem słuchania, gdy jest on skonfigurowany do inaddr_any dla dowolnego adresu lokalnego.
Metoda wiązania może ponownie wykorzystać adres lokalny po użyciu flagi SO_REUSEADDR. Zauważ, że adres lokalny, który składa się z adresu IP i numeru portu, oznacza, że dwa adresy lokalne mogą współistnieć same w sobie, jeśli jakakolwiek część IP lub numer portu jest inna, a zatem nie wymaga zastosowania niniejszej flagi. Adresu lokalnego nie można wykorzystać za pomocą tego parametru, jeśli do niego już uzyskano gniazdo, które jest w stanie słuchania. Gdy lokalny adres gniazda znajduje się w stanie słuchania, a komponent IP adres. Bind nie może już podtrzymywać żadnych lokalnych adresów dla tego portu, nawet przy tym argumencie.
Przykład:
Oto kod klienta używany dla klientów do łączenia się z serwerem za pomocą dwóch osobnych adresów IP. Klient w poniższym przykładzie chce połączyć się z serwerem, który używa innego numeru portu, ale ten sam adres IP. Lokalny adres IP hosta i wartość portu zostały przekazane do funkcji Connect_TCP w pierwszym wywołaniu, w którym zostały ustawione na 8888.
Jednak po powiązaniu z adresem lokalnym system użył domeny gniazda UNIX do wykonania drugiego połączenia gniazda, w którym adres IP pozostał taki sam, ale numer portu został zmieniony na 7777. Oznacza to, że klient jest podłączony do dwóch różnych adresów gniazda na jedno żądanie TCP, co jest możliwe, ponieważ adresy są różne. Ten kod łączy się z komputerem docelowym po pierwszym powiązaniu adresu lokalnego. Dwie próby wiązania powinny zakończyć się powodzeniem, ponieważ, jak pokazuje wyżej wspomniana, część IP lokalnych adresów dwóch połączeń powiązanych jest różna.
Wykorzystując terminal wiersza poleceń Linux, skompiluj kod za pomocą kompilatora GCC dla kodu języka C:
Korzystając z polecenia NCAT, naśladujemy serwer:
Aby wyświetlić każdy stan gniazda dla numeru portu 7777, użyj polecenia SS:
Poniższe wyjście wyświetla status gniazda dla numeru portu 7777:
Jak widać z Pevious zrzut ekranu, nie ma teraz innego połączenia, a serwer NCAT słucha na porcie 7777. Po wykonaniu pliku wyjściowego utworzonego na etapie kompilacji wykonaj go.
Teraz wykonaj to samo polecenie po wykonaniu pliku wyjściowego poprzedniego kodu w terminalu Linux. Zauważ, że istnieją dwa połączenia z połączeniem Connect_TCP, wówczas podczas tych połączeń ustalane są cztery połączenia.
Teraz, gdy dwa połączenia są pomyślnie wykonane, jedno używa 127.0.0.1 i port 7777, a drugi za pomocą portu 8888, otrzymaliśmy następujące dane wyjściowe. Na poniższym ekranie istnieją cztery połączenia, ponieważ dwukrotnie wywołyliśmy metodę Connect TCP:
Widoczne są cztery estab (ustalone) połączenia stanowe, co jest normalne, ponieważ dane wyjściowe jest odpowiednio od strony serwera i strony klienta. Pierwsze trzy linie są zapisywane z perspektywy serwera, podczas gdy kolejne dwa są prezentowane z perspektywy klienta. Nazwa procesu w tle również to pokazuje. Przed dołączeniem klient może podłączyć wiele lokalnych adresów IP, a serwer może zrobić to samo, używając celu. Może wiązać się z różnymi adresami lokalnymi przed monitorowaniem bez argumentu SO_REUSEADDR. Nie zilustrujemy tego teraz, ponieważ kod oprogramowania jest podobny. Kod najpierw wiąże adres lokalny do adresu docelowego, czyli albo 127.0.0.1: 7777 lub 127.0.0.1: 7778, a następnie wykonaj połączenie z tymi adresami IP.
Kiedy uruchamiamy tego klienta, wyświetla się on na ekranie „adres już używany”, wskazując, że pierwszy klient ma ten adres. Poprzedni kod jest teraz modyfikowany, po prostu dodając jeszcze kilka wierszy kodu do użycia flagi SouseAddr. Chcemy podłączyć nasz klient z podobnym adresem gniazda, który jest już używany lub posiadany przez innego klienta. Oto fragment kodu zmodyfikowanego kodu:
Użyliśmy edytora VIM do otwarcia pliku i dodania kodu w trybie Wstaw.
Ponownie skompiluj kod. Ale zanim to zrobisz, zwróć uwagę na następujące: Utwórz nowy plik lub użyj istniejącego i zmodyfikuj nazwę pliku wyjściowego podczas kompilacji. Po kompilacji wykonaj plik wyjściowy za pomocą terminalu wiersza poleceń. Po wykonaniu widzimy, że klient jest podłączony do tego samego adresu IP i numeru portu, w którym podłączony był nasz pierwszy klient. To dlatego, że użyliśmy flagi SO_REUSEADDR.
Wniosek
Chodzi o użycie parametru gniazda SO_REUSEADDR, który jest flagą typu logicznego w języku C. Widzieliśmy przykład za pomocą parametru gniazda SO_REUSEADDR, aby określić, czy adres lokalny ponownie używany w dalszych programach lub wątkach powinien być dozwolony przez kierunki używane do uwierzytelniania adresów tylko wtedy, gdy w systemie BID.