Tamanho máximo de pacote para uma conexão TCP

196

Qual é o tamanho máximo de pacote para uma conexão TCP ou como posso obter o tamanho máximo de pacote?

Alexa
fonte
24
O TCP é baseado em fluxo. Existe um motivo específico para você se preocupar com pacotes individuais?
Matti Virkkunen
27
Como as camadas abaixo são baseadas em pacotes ... Implementação Típica -> Camada 1 - Ethernet PHY, Camada 2 - Ethernet MAC (Definição de Pacotes MAC, Camada 3 - Protocolo Internet (Definição de Pacotes IP), Camada 4 - TCP (Protocolo de Controle de Transmissão) ) - Usa serviço baseado em pacotes abaixo dele #
2
Não existe um 'pacote TCP'. Existem segmentos TCP , cujo comprimento é descrito por uma palavra de 32 bits, e estão contidos dentro ou através de pacotes IP , cujo comprimento é descrito em 16 bits. Há também quadros Ethernet, que contêm todas essas coisas. De quais dessas coisas você está perguntando? De qualquer forma, se você estiver usando o TCP, não precisará se preocupar com nenhum deles: o TCP e o IP cuidam de tudo.
Marquês de Lorne,

Respostas:

178

A limitação absoluta no tamanho do pacote TCP é de 64K (65535 bytes), mas, na praticidade, é muito maior que o tamanho de qualquer pacote que você verá, porque as camadas inferiores (por exemplo, ethernet) têm tamanhos de pacote mais baixos.

A MTU (unidade máxima de transmissão) para Ethernet, por exemplo, é de 1500 bytes. Alguns tipos de redes (como o Token Ring) têm MTUs maiores e alguns tipos têm MTUs menores, mas os valores são fixos para cada tecnologia física.

Éter
fonte
15
"Mas os valores são fixos para cada tecnologia física" - isso não é verdade. A Ethernet costumava ter uma MTU máxima de 1500, mas você poderia usar uma menor. Com o advento dos jumbo-frames, não há um máximo real especificado, e o máximo varia dependendo do hardware e do driver.
turbilhão
4
@ Whirl: verdade, eles são configuráveis, mas geralmente não são; "configurável" é subjetivo, porque seria necessário investigar o kernel para fazer isso. Não é algo que se possa mexer no nível do aplicativo, que é onde o OP parece estar.
Éter
3
@HiroProtagonist: 1500 é o máximo, portanto, ter 600 não é surpreendente.
Nicolas Raoul
28
por que é 64K (65535 bytes) a limitação? Como o atributo Tamanho da Janela no Cabeçalho TCP é de apenas 16 bits. Eu só queria mencionar, poderia ajudar alguém em algum momento ..... ótima resposta btw @Ether!
Cacho Santa
2
Além disso, é possível aumentar usando a escala da janela. Nesse caso, o máximo é 1 GiB
Martin Melka 24/04
86

Essa é uma excelente pergunta e eu me deparo com isso muito no trabalho, na verdade. Existem muitas respostas "tecnicamente corretas", como 65k e 1500. Eu trabalhei muito escrevendo interfaces de rede e o uso de 65k é bobo, e 1500 também pode causar grandes problemas. Meu trabalho é desenvolvido em diferentes hardwares / plataformas / roteadores e, para ser sincero, o local onde começo é de 1400 bytes. Se você PRECISA de mais de 1400, pode começar a subir rapidamente, provavelmente poderá ir para 1450 e, às vezes, para 1480'ish? Se você precisar de mais do que isso, é claro que precisará dividir em 2 pacotes, dos quais existem várias maneiras óbvias de fazer.

O problema é que você está falando sobre criar um pacote de dados e gravá-lo via TCP, mas é claro que existem dados de cabeçalho anexados e assim por diante, para que você tenha uma "bagagem" que o leva a 1500 ou mais além. muito hardware tem limites mais baixos.

Se você insistir, poderá obter coisas realmente estranhas. Dados truncados, obviamente, ou dados que eu raramente vi. Dados corrompidos também raramente, mas certamente acontecem.

Nektarios
fonte
Por que as solicitações GET têm em média cerca de 600 bytes?
10
Você quer dizer 64K, não 65K. Não sei o que você quer dizer com 'o lugar que eu começo é 1400 bytes'. Você não precisa se preocupar com tamanhos de pacote na API TCP. Ele cuida de determinar e observar o caminho MTU. Não há motivo para não escrever 2G em um, send()se for conveniente.
Marquês de Lorne
19
Você 1480'ishdeveria ser 1460. O cabeçalho IP e o TCP ocupam pelo menos 20 bytes cada (a menos que campos de cabeçalho opcionais sejam usados) e, portanto, o máximo para Ethernet (sem quadro Jumbo) é 1500 - 20 -20 = 1460.
Eugene Beresovsky
2
Eu vi via wireshark que um servidor envia pacotes grandes (mais de 1400 bytes) e o cliente o recebe desmontado como poucos pacotes de 1400 bytes no máximo. quem é responsável pela desmontagem do pacote? @Nektario ...?
inbaly
2
@EugeneBeresovsky bem, com os cabeçalhos opcionais que são + até mais 40 bytes, mas é variável, então 1420 parece o limite. com a sugestão de 1400, você recebe um pouco de preenchimento. eu vou com 1408 desde que é divisível por 128
Garet Claborn
22

No nível do aplicativo, o aplicativo usa o TCP como um protocolo orientado a fluxo. O TCP, por sua vez, possui segmentos e abstrai os detalhes do trabalho com pacotes IP não confiáveis.

O TCP lida com segmentos em vez de pacotes. Cada segmento TCP possui um número de sequência que está contido dentro de um cabeçalho TCP. Os dados reais enviados em um segmento TCP são variáveis.

Há um valor para getsockopt suportado em alguns sistemas operacionais que você pode usar chamado TCP_MAXSEG, que recupera o tamanho máximo do segmento TCP (MSS). Não é suportado em todos os sistemas operacionais.

Não sei exatamente o que você está tentando fazer, mas se você deseja reduzir o tamanho do buffer usado, também pode procurar: SO_SNDBUF e SO_RCVBUF.

Brian R. Bondy
fonte
Gostaria de saber se você pode usar o TCP como uma fila de mensagens, se você pode caber todas as suas mensagens dentro de um grande pacote TCP?
precisa saber é o seguinte
4

Não há pacotes na API TCP.

Geralmente, existem pacotes nos protocolos subjacentes, como quando o TCP é feito sobre IP, no qual você não tem interesse, porque eles não têm nada a ver com o usuário, exceto pelas otimizações de desempenho muito delicadas nas quais você provavelmente não está interessado (de acordo com o formulação da questão).

Se você perguntar qual é o número máximo de bytes que você pode send()em uma chamada de API, isso depende da implementação e das configurações. Você normalmente chama send () para pedaços de até vários kilobytes e está sempre pronto para o sistema se recusar a aceitá-lo total ou parcialmente. Nesse caso, você precisará gerenciar manualmente a divisão em pedaços menores para alimentar seus dados no API send () TCP.

Pavel Radzivilovsky
fonte
8
O TCP possui pacotes, bem como um cabeçalho de pacote, parte do qual se sobrepõe ao cabeçalho IP. Só porque você não deveria ver, isso não significa que não existe. O TCP é sempre feito sobre IP. Você não pode fazer isso sem IP porque os cabeçalhos se sobrepõem.
turbilhão
23
O @WhirlWind TCP possui segmentos. IP tem pacotes.
Marquês de Lorne
1
O TCP possui segmentos (ou chame-os de pacotes, tudo bem). A API do TCP não possui pacotes.
Pavel Radzivilovsky
13
@NathanLong O mal é que você causa confusão desnecessária. O TCP possui segmentos, o UDP possui datagramas, o IP possui pacotes, a Ethernet possui quadros, ...
Marquês de Lorne
1
@Chexxor Então, qual idioma você usará para descrever segmentos TCP dentro de pacotes IP dentro de quadros Ethernet? Não há necessidade de confundir o problema usando o mesmo termo para coisas diferentes, quando os autores dessas coisas se esforçam muito para usar termos diferentes.
Marquês de Lorne
3

Geralmente, isso depende da interface que a conexão está usando. Provavelmente, você pode usar um ioctl () para obter a MTU e, se for Ethernet, geralmente poderá obter o tamanho máximo de pacote subtraindo o tamanho do cabeçalho do hardware, que é 14 para Ethernet sem VLAN.

Este é apenas o caso se a MTU for pelo menos tão grande na rede. O TCP pode usar o caminho MTU discovery para reduzir seu MTU efetivo.

A questão é: por que você se importa?

WhirlWind
fonte
6
Isso só lhe dá o tamanho máximo de pacote no primeiro link. Tanto quanto eu sei, qualquer outro nó ao longo da rota pode não gostar de pacotes grandes e pode ser dividido em qualquer lugar ao longo do caminho.
Matti Virkkunen
Sim, isso é verdade ... então sua pergunta é boa - por que você quer isso?
turbilhão
Quero vídeos de transmissão / imagens através de uma conexão LAN
Alexa
1
Como o TCP é orientado para o fluxo, por que isso importa?
turbilhão
3

Se você estiver com máquinas Linux, "ifconfig eth0 mtu 9000 up" é o comando para configurar o MTU para uma interface. No entanto, devo dizer, o MTU grande tem algumas desvantagens se a transmissão da rede não é tão estável e pode usar mais memórias de espaço no kernel.

DAG
fonte
3

Parece que a maioria dos sites na Internet usa 1460 bytes para o valor de MTU. Às vezes, é 1452 e, se você estiver em uma VPN, ele diminuirá ainda mais os cabeçalhos IPSec.

O tamanho da janela padrão varia um pouco até um máximo de 65535 bytes. Eu uso http://tcpcheck.com para verificar meus próprios valores de IP de origem e verificar o que outros fornecedores de Internet estão usando.

David McCulloch
fonte
2

Uma solução pode ser definir a opção de soquete TCP_MAXSEG ( http://linux.die.net/man/7/tcp ) para um valor "seguro" com a rede subjacente (por exemplo, definir 1400 para ser seguro na ethernet) e depois use um buffer grande na chamada do sistema de envio. Dessa forma, pode haver menos chamadas do sistema que são caras. O kernel dividirá os dados para corresponder ao MSS.

Dessa forma, você pode evitar dados truncados e seu aplicativo não precisa se preocupar com buffers pequenos.

hashtpaa
fonte
2

O tamanho do pacote para uma configuração TCP no protocolo IP (Ip4). Para este campo (TL), 16 bits são alocados, portanto o tamanho máximo do pacote é 65535 bytes: detalhes do protocolo IP

Ziegfried
fonte