Maksymalny rozmiar pakietu dla połączenia TCP


197

Jaki jest maksymalny rozmiar pakietu dla połączenia TCP lub jak mogę uzyskać maksymalny rozmiar pakietu?


24
TCP jest oparty na strumieniu. Czy jest jakiś konkretny powód, dla którego martwisz się o poszczególne pakiety?
Matti Virkkunen,

27
Ponieważ poniższe warstwy są oparte na pakietach ... Typowa implementacja -> Warstwa 1 - Ethernet PHY, Warstwa 2 - Ethernet MAC (Definicja pakietu MAC, Warstwa 3 - Protokół internetowy (Definicja pakietu IP), Warstwa 4 - TCP (Protokół kontroli transmisji ) - Używa poniżej usługi opartej na pakietach

2
Nie ma czegoś takiego jak „pakiet TCP”. Istnieją segmenty TCP , których długość jest opisana 32-bitowym słowem i są zawarte w pakietach IP lub między nimi , których długość jest opisana w 16 bitach. Istnieją również ramki Ethernet, które zawierają wszystkie te rzeczy. O które z tych rzeczy pytasz? W każdym razie, jeśli używasz TCP, nie musisz się w żaden sposób martwić o żaden z nich: TCP i IP dbają o to wszystko za Ciebie.
Markiz Lorne

Odpowiedzi:


178

Bezwzględne ograniczenie rozmiaru pakietu TCP wynosi 64 KB (65535 bajtów), ale w praktyce jest to znacznie więcej niż rozmiar dowolnego pakietu, który zobaczysz, ponieważ niższe warstwy (np. Ethernet) mają mniejsze rozmiary pakietów.

Na przykład MTU (Maximum Transmission Unit) dla Ethernetu wynosi 1500 bajtów. Niektóre typy sieci (jak Token Ring) mają większe MTU, a niektóre typy mają mniejsze MTU, ale wartości są ustalone dla każdej technologii fizycznej.


15
„Ale wartości są ustalone dla każdej technologii fizycznej” - to nieprawda. Wcześniej Ethernet miał maksymalną MTU równą 1500, ale można było użyć niższej. Wraz z pojawieniem się ramek jumbo, nie ma rzeczywistego określonego maksimum, a maksimum różni się w zależności od sprzętu i sterownika.
WhirlWind,

4
@ Whirl: prawda, można je konfigurować, ale generalnie nie są; „konfigurowalny” jest subiektywny, ponieważ w tym celu należałoby zagłębić się w jądro. Nie jest to coś, co można majstrować na poziomie aplikacji, na którym wydaje się być OP.
Eter

3
@HiroProtagonist: 1500 to maksimum, więc posiadanie 600 nie jest zaskakujące.
Nicolas Raoul,

28
dlaczego ograniczenie to wynosi 64 KB (65535 bajtów)? Ponieważ atrybut Rozmiar okna w nagłówku TCP ma tylko 16 bitów. Chciałem tylko wspomnieć, może kiedyś komuś pomóc ... świetna odpowiedź btw @Ether!
Cacho Santa

2
Można go również zwiększyć, stosując skalowanie okien. W takim przypadku maksymalna wartość to 1 GiB
Martin Melka

86

To doskonałe pytanie i tak naprawdę wpadam na to w pracy. Istnieje wiele „poprawnych technicznie” odpowiedzi, takich jak 65k i 1500. Zrobiłem dużo pracy, pisząc interfejsy sieciowe, a używanie 65k jest głupie, a 1500 może również sprawić ci duże kłopoty. Moja praca dotyczy wielu różnych urządzeń / platform / routerów i, szczerze mówiąc, miejsce, w którym zaczynam, to 1400 bajtów. Jeśli POTRZEBUJESZ więcej niż 1400, możesz zacząć podnosić się w górę, prawdopodobnie możesz przejść do 1450, a czasem do 1480? Jeśli potrzebujesz więcej, to oczywiście musisz podzielić na 2 pakiety, z których istnieje kilka oczywistych sposobów zrobienia ..

Problem polega na tym, że mówisz o tworzeniu pakietu danych i zapisywaniu go za pomocą protokołu TCP, ale oczywiście istnieją dane nagłówkowe itd., Więc masz „bagaż”, który zabiera Cię do 1500 lub więcej… a także dużo sprzętu ma niższe limity.

Jeśli go „popchniesz”, możesz mieć naprawdę dziwne rzeczy. Obcięte dane lub oczywiście upuszczone dane, które rzadko widuję. Uszkodzone dane również rzadko, ale na pewno się zdarzają.


Dlaczego żądania GET wynoszą średnio około 600 bajtów?

10
Masz na myśli 64 tys., A nie 65 tys. Nie wiem, co rozumiesz przez „miejsce, w którym zaczynam to 1400 bajtów”. Nie musisz martwić się o rozmiary pakietów w interfejsie API TCP. Zajmuje się określaniem i obserwowaniem MTU ścieżki. Nie ma powodu, dla którego nie można napisać 2G w jednym, send()jeśli jest to wygodne.
Markiz Lorne

19
Twój 1480'ishpowinien być 1460. Nagłówek IP i nagłówek TCP zajmują co najmniej 20 bajtów (chyba że używane są opcjonalne pola nagłówka), a zatem maksymalna wartość dla (innej niż Jumbo) sieci Ethernet wynosi 1500 - 20 -20 = 1460.
Eugene Beresovsky,

2
Widziałem za pośrednictwem wireshark, że serwer wysyła duże pakiety (ponad 1400 bajtów), a klient odbiera je zdemontowane jako kilka pakietów o maksymalnej długości 1400 bajtów. kto jest odpowiedzialny za demontaż pakietu? @Nektario ...?
inbaly

2
@EugeneBeresovsky dobrze z opcjonalnymi nagłówkami, które mają + 40 dodatkowych bajtów, ale jest zmienna, więc 1420 wydaje się limitem. z sugestią 1400 dostajesz trochę wypełnienia. pójdę z 1408, ponieważ jest podzielna przez 128
Garet Claborn

22

Na poziomie aplikacji aplikacja używa protokołu TCP jako protokołu zorientowanego na strumień. Z kolei TCP dzieli segmenty i streszcza szczegóły pracy z niewiarygodnymi pakietami IP.

TCP zajmuje się segmentami zamiast pakietów. Każdy segment TCP ma numer kolejny zawarty w nagłówku TCP. Rzeczywiste dane wysyłane w segmencie TCP są zmienne.

Istnieje wartość parametru getsockopt obsługiwana w niektórych systemach operacyjnych o nazwie TCP_MAXSEG, która pobiera maksymalny rozmiar segmentu TCP (MSS). Nie jest jednak obsługiwane we wszystkich systemach operacyjnych.

Nie jestem pewien, co dokładnie próbujesz zrobić, ale jeśli chcesz zmniejszyć rozmiar używanego bufora, możesz również zajrzeć do: SO_SNDBUF i SO_RCVBUF.


Zastanawiam się, czy możesz użyć TCP jako kolejki wiadomości, jeśli zmieścisz wszystkie wiadomości w dużym pakiecie TCP?
CMCDragonkai


4

W interfejsie API TCP nie ma pakietów.

Protokoły bazowe często zawierają pakiety, na przykład gdy TCP jest wykonywany przez IP, co nie jest tym zainteresowane, ponieważ nie mają one nic wspólnego z użytkownikiem, z wyjątkiem bardzo delikatnych optymalizacji wydajności, którymi prawdopodobnie nie jesteś zainteresowany (zgodnie z sformułowanie pytania).

Jeśli zapytasz, jaka jest maksymalna liczba bajtów send()w jednym wywołaniu API, zależy to od implementacji i ustawień. Zwykle wywołujesz send () dla fragmentów o wielkości do kilku kilobajtów i zawsze jesteś gotowy, aby system odmówił przyjęcia go całkowicie lub częściowo, w takim przypadku będziesz musiał ręcznie zarządzać dzieleniem na mniejsze fragmenty, aby wprowadzić dane do API send () TCP.


8
TCP ma pakiety, a także nagłówek pakietu, którego część pokrywa się z nagłówkiem IP. To, że nie powinieneś tego widzieć, nie oznacza, że ​​nie istnieje. TCP jest zawsze wykonywany przez IP. Nie można tego zrobić bez adresu IP, ponieważ nagłówki się pokrywają.
WhirlWind

23
@WhirlWind TCP ma segmenty. IP ma pakiety.
Markiz Lorne

1
TCP ma segmenty (lub nazywaj je pakietami, jest w porządku). TCP API nie ma pakietów.
Pavel Radzivilovsky

13
@NathanLong Szkodą jest to, że powodujesz niepotrzebne zamieszanie. TCP ma segmenty, UDP ma datagramy, IP ma pakiety, Ethernet ma ramki, ...
Markiz Lorne

1
@Chexxor Więc jakiego języka użyjesz do opisu segmentów TCP w pakietach IP wewnątrz ramek Ethernet? Nie ma potrzeby, aby mylić problem, używając tego samego terminu dla różnych rzeczy, gdy autorzy tych rzeczy mieli wiele problemów z użyciem różnych terminów.
Markiz Lorne

3

Zasadniczo będzie to zależeć od interfejsu używanego przez połączenie. Prawdopodobnie możesz użyć metody ioctl (), aby uzyskać MTU, a jeśli jest to sieć Ethernet, zwykle możesz uzyskać maksymalny rozmiar pakietu, odejmując od niego rozmiar nagłówka sprzętowego, który wynosi 14 dla sieci Ethernet bez VLAN.

Dzieje się tak tylko wtedy, gdy MTU jest co najmniej tak duża w sieci. TCP może użyć funkcji wykrywania MTU ścieżki, aby zmniejszyć efektywną MTU.

Pytanie brzmi: dlaczego cię to obchodzi?


6
To zapewni ci tylko maksymalny rozmiar pakietu przy pierwszym łączu. O ile mi wiadomo, każdy inny węzeł na trasie może nie lubić dużych pakietów i może zostać podzielony w dowolnym miejscu na ścieżce.
Matti Virkkunen,

Tak, to prawda ... więc twoje pytanie jest dobre - dlaczego miałbyś tego chcieć?
WhirlWind,

Chcę przesyłać filmy / obrazy przez połączenie LAN
Alexa

1
Skoro TCP jest zorientowany na strumień, dlaczego to ma znaczenie?
WhirlWind,

3

W przypadku komputerów z systemem Linux polecenie „ifconfig eth0 mtu 9000 up” to polecenie ustawienia MTU dla interfejsu. Muszę jednak powiedzieć, że duża MTU ma pewne wady, jeśli transmisja sieciowa nie jest tak stabilna i może wykorzystywać więcej pamięci miejsca w jądrze.


3

Wydaje się, że większość stron internetowych używa 1460 bajtów dla wartości MTU. Czasami jest 1452, a jeśli korzystasz z VPN, spadnie jeszcze bardziej dla nagłówków IPSec.

Domyślny rozmiar okna zmienia się całkiem do maksymalnie 65535 bajtów. Korzystam z http://tcpcheck.com, aby przeglądać własne wartości źródłowe IP i sprawdzać, jakich używają inni dostawcy Internetu.


2

Jednym z rozwiązań może być ustawienie opcji gniazda TCP_MAXSEG ( http://linux.die.net/man/7/tcp ) na wartość „bezpieczną” w sieci bazowej (np. Ustawioną na 1400, aby była bezpieczna w sieci Ethernet), a następnie użyj dużego bufora do wysyłania wywołania systemowego. W ten sposób może być mniej kosztownych wywołań systemowych. Jądro podzieli dane, aby dopasować MSS.

W ten sposób można uniknąć obciętych danych, a aplikacja nie musi martwić się o małe bufory.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.