Tamaño máximo de paquete para una conexión TCP

196

¿Cuál es el tamaño máximo de paquete para una conexión TCP o cómo puedo obtener el tamaño máximo de paquete?

Alexa
fuente
24
TCP está basado en transmisión. ¿Hay alguna razón específica por la que te preocupes por los paquetes individuales?
Matti Virkkunen
27
Debido a que las capas debajo están basadas en paquetes ... Implementación típica -> Capa 1 - PHY de Ethernet, Capa 2 - MAC de Ethernet (Definición de paquete MAC, Capa 3 - Protocolo de Internet (Definición de paquete IP), Capa 4 - TCP (Protocolo de control de transmisión ) - Utiliza un servicio basado en paquetes debajo de él.
2
No existe tal cosa como un 'paquete TCP'. Hay segmentos TCP , cuya longitud se describe mediante una palabra de 32 bits, y están contenidos dentro o entre paquetes IP , cuya longitud se describe en 16 bits. También hay tramas de Ethernet, que contienen todas estas cosas. ¿Sobre cuáles de estas cosas preguntas? En cualquier caso, si está utilizando TCP, no tiene que preocuparse por ninguno de ellos de ninguna manera: TCP e IP se ocupan de todo por usted.
Marqués de Lorne

Respuestas:

178

La limitación absoluta en el tamaño del paquete TCP es 64K (65535 bytes), pero en la práctica esto es mucho más grande que el tamaño de cualquier paquete que verá, porque las capas más bajas (por ejemplo, ethernet) tienen tamaños de paquete más bajos.

La MTU (Unidad de transmisión máxima) para Ethernet, por ejemplo, es de 1500 bytes. Algunos tipos de redes (como Token Ring) tienen MTU más grandes, y algunos tipos tienen MTU más pequeñas, pero los valores son fijos para cada tecnología física.

Éter
fuente
15
"Pero los valores son fijos para cada tecnología física", esto no es cierto. Ethernet solía tener una MTU máxima de 1500, pero podría usar una más baja. Con la llegada de los marcos jumbo, no hay un máximo real especificado, y el máximo varía según el hardware y el controlador.
WhirlWind
44
@Whirl: es cierto, son configurables, pero en general no lo son; "configurable" es subjetivo porque uno tendría que profundizar en el núcleo para hacerlo. No es algo con lo que uno pueda jugar a nivel de aplicación, que es donde parece estar el OP.
Ether
3
@HiroProtagonist: 1500 es un máximo, por lo que tener 600 no es sorprendente.
Nicolas Raoul
28
¿Por qué es 64K (65535 bytes) la limitación? Porque el atributo Tamaño de ventana en el encabezado TCP es de solo 16 bits. Solo quería mencionar, podría ayudar a alguien en algún momento ... ¡gran respuesta por cierto @Ether!
Cacho Santa
2
Además, es posible aumentarlo usando el escalado de ventanas. En ese caso, el máximo es 1 GiB
Martin Melka
86

Esta es una excelente pregunta y realmente me encuentro con esto en el trabajo. Hay muchas respuestas "técnicamente correctas", como 65k y 1500. He trabajado mucho escribiendo interfaces de red y usando 65k es una tontería, y 1500 también puede meterte en grandes problemas. Mi trabajo abarca muchos hardware / plataformas / enrutadores diferentes, y para ser sincero, el lugar donde empiezo es 1400 bytes. Si NECESITAS más de 1400, puedes comenzar a aumentar poco a poco, ¿probablemente puedas ir a 1450 y a veces a 1480? Si necesita más que eso, por supuesto, necesita dividirlo en 2 paquetes, de los cuales hay varias formas obvias de hacerlo ...

El problema es que está hablando de crear un paquete de datos y escribirlo a través de TCP, pero, por supuesto, hay datos de encabezado añadidos y demás, por lo que tiene un "equipaje" que lo lleva a 1500 o más ... y también a gran cantidad de hardware tiene límites inferiores.

Si lo "empujas", puedes hacer que ocurran algunas cosas realmente extrañas. Datos truncados, obviamente, o datos descartados que he visto raramente. Los datos dañados también rara vez, pero ciertamente suceden.

Nektarios
fuente
¿Por qué las solicitudes GET tienen un promedio de 600 bytes?
10
Te refieres a 64K, no 65K. No sé a qué te refieres con 'el lugar donde comienzo es 1400 bytes'. No tiene que preocuparse por el tamaño de los paquetes en la API TCP. Se encarga de determinar y observar la ruta MTU. No hay ninguna razón por la que no pueda escribir 2G en uno send()si es conveniente.
Marqués de Lorne
19
Tu 1480'ishdeberías ser 1460. El encabezado IP y el encabezado TCP ocupan al menos 20 bytes cada uno (a menos que se usen campos de encabezado opcionales) y, por lo tanto, el máximo para Ethernet (no Jumbo frame) es 1500 - 20 -20 = 1460.
Eugene Beresovsky
2
He visto a través de wireshark que un servidor envía paquetes grandes (más de 1400 bytes) y el cliente lo recibe desmontado como pocos paquetes de 1400 bytes como máximo. ¿Quién es responsable del desmontaje del paquete? @Nektario ...?
inbaly
2
@EugeneBeresovsky bien con los encabezados opcionales que son + hasta 40 bytes más, pero es variable, por lo que 1420 parecería el límite. con la sugerencia de 1400 obtienes un poco de relleno. iré con 1408 ya que es divisible por 128
Garet Claborn
22

A nivel de la aplicación, la aplicación utiliza TCP como un protocolo orientado a la transmisión. TCP a su vez tiene segmentos y extrae los detalles de trabajar con paquetes IP poco confiables.

TCP trata con segmentos en lugar de paquetes. Cada segmento TCP tiene un número de secuencia que está contenido dentro de un encabezado TCP. Los datos reales enviados en un segmento TCP son variables.

Hay un valor para getsockopt que es compatible con algunos sistemas operativos que puede usar llamado TCP_MAXSEG que recupera el tamaño máximo de segmento TCP (MSS). Sin embargo, no es compatible con todos los sistemas operativos.

No estoy seguro de qué es exactamente lo que está tratando de hacer, pero si desea reducir el tamaño del búfer que se usa, también puede consultar: SO_SNDBUF y SO_RCVBUF.

Brian R. Bondy
fuente
Me pregunto si puede usar TCP como una cola de mensajes si puede ajustar todos sus mensajes dentro de un paquete TCP grande.
CMCDragonkai
4

No hay paquetes en la API TCP.

A menudo hay paquetes en los protocolos subyacentes, como cuando TCP se realiza sobre IP, en los que no tiene interés, porque no tienen nada que ver con el usuario, excepto las optimizaciones de rendimiento muy delicadas que probablemente no le interesen (de acuerdo con formulación de la pregunta).

Si pregunta cuál es el número máximo de bytes que puede send()en una llamada API, esto depende de la implementación y la configuración. Por lo general, llamaría a send () para fragmentos de hasta varios kilobytes, y siempre estará listo para que el sistema se niegue a aceptarlo total o parcialmente, en cuyo caso tendrá que gestionar manualmente la división en fragmentos más pequeños para alimentar sus datos en el TCP send () API.

Pavel Radzivilovsky
fuente
8
TCP tiene paquetes, así como un encabezado de paquete, parte del cual se superpone al encabezado IP. Solo porque se supone que no debes verlo no significa que no exista. TCP siempre se realiza sobre IP. No puede hacerlo sin IP porque los encabezados se superponen.
WhirlWind
23
@WhirlWind TCP tiene segmentos. IP tiene paquetes.
Marqués de Lorne
1
TCP tiene segmentos (o llámalos paquetes, está bien). La API TCP no tiene paquetes.
Pavel Radzivilovsky
13
@NathanLong El daño es que causa confusión innecesaria. TCP tiene segmentos, UDP tiene datagramas, IP tiene paquetes, Ethernet tiene tramas, ...
Marqués de Lorne
1
@Chexxor Entonces, ¿qué idioma utilizará para describir los segmentos TCP dentro de los paquetes IP dentro de las tramas Ethernet? No hay necesidad de confundir el problema usando el mismo término para diferentes cosas, cuando los autores de estas cosas se han tomado muchas molestias para usar diferentes términos.
Marqués de Lorne
3

En general, esto dependerá de la interfaz que utilice la conexión. Probablemente pueda usar un ioctl () para obtener la MTU, y si es ethernet, generalmente puede obtener el tamaño máximo de paquete restando el tamaño del encabezado de hardware, que es 14 para ethernet sin VLAN.

Este es solo el caso si la MTU es al menos tan grande en toda la red. TCP puede utilizar el descubrimiento de MTU de ruta para reducir su MTU efectiva.

La pregunta es, ¿por qué te importa?

Torbellino
fuente
66
Eso solo le dará el tamaño máximo de paquete en el primer enlace. Hasta donde yo sé, a cualquier otro nodo a lo largo de la ruta se le permite que no le gusten los paquetes grandes y podría dividirse en cualquier parte del camino.
Matti Virkkunen
Sí, eso es cierto ... así que tu pregunta es buena, ¿por qué quieres esto?
WhirlWind
Quiero transmitir videos / imágenes a través de una conexión LAN
Alexa
1
Dado que TCP está orientado a la transmisión, ¿por qué es importante?
WhirlWind
3

Si está con máquinas Linux, "ifconfig eth0 mtu 9000 up" es el comando para configurar la MTU para una interfaz. Sin embargo, debo decir que la gran MTU tiene algunas desventajas si la transmisión de la red no es tan estable y puede usar más memorias de espacio del núcleo.

TROZO DE CUERO
fuente
3

Parece que la mayoría de los sitios web en Internet usan 1460 bytes por el valor de MTU. A veces es 1452 y si está en una VPN, caerá aún más para los encabezados IPSec.

El tamaño predeterminado de la ventana varía bastante hasta un máximo de 65535 bytes. Utilizo http://tcpcheck.com para ver mis propios valores de IP de origen y verificar qué otros proveedores de Internet están utilizando.

David McCulloch
fuente
2

Una solución puede ser establecer la opción de socket TCP_MAXSEG ( http://linux.die.net/man/7/tcp ) en un valor que sea "seguro" con la red subyacente (por ejemplo, establecer en 1400 para que sea seguro en Ethernet) y luego use un búfer grande en la llamada al sistema de envío. De esta manera puede haber menos llamadas al sistema que son caras. Kernel dividirá los datos para que coincidan con MSS.

De esta manera, puede evitar datos truncados y su aplicación no tiene que preocuparse por pequeños buffers.

hashtpaa
fuente
2

El tamaño del paquete para una configuración TCP en el protocolo IP (Ip4). Para este campo (TL), se asignan 16 bits, en consecuencia, el tamaño máximo del paquete es 65535 bytes: detalles del protocolo IP

Ziegfried
fuente