Pacotes TCP podem chegar ao receptor em pedaços?
Por exemplo, se eu enviar 20 bytes usando o protocolo TCP, posso ter 100% de certeza de que receberei exatamente 20 bytes de uma só vez, não 10 bytes e outros 10 bytes?
E a mesma pergunta para o protocolo UDP.
Eu sei que o UDP não é confiável e os pacotes não podem chegar nem chegar em ordem diferente, mas e quanto a um único pacote? Se chegar, posso ter certeza de que é um pacote completo, não um pedaço?
networking
tcp
udp
iamnp
fonte
fonte
Respostas:
Sim. O IP suporta fragmentação, embora o TCP geralmente tente determinar o caminho MTU e mantenha seus pacotes menores que por motivos de desempenho. A fragmentação aumenta a taxa de perda de datagramas catastroficamente. Se um caminho tem uma taxa de perda de 10% de pacotes, fragmentar um datagrama em dois pacotes torna a taxa de perda de datagrama quase 20%. (Se um dos pacotes for perdido, o datagrama será perdido.)
Você não precisa se preocupar com isso, e a camada TCP também não. A camada IP remonta pacotes em datagramas inteiros.
Não, mas isso não tem nada a ver com pacotes. O TCP é, fundamentalmente, um protocolo de fluxo de bytes que não preserva os limites das mensagens do aplicativo.
O mesmo vale para o TCP. Pacotes são pacotes. A diferença é que o TCP tem novas tentativas e reordenações incorporadas ao protocolo, enquanto o UDP não.
Não, mas esse não é o seu problema. O protocolo UDP trata da remontagem de datagramas. Isso faz parte do seu trabalho. (Na verdade, o protocolo IP faz isso para o protocolo UDP, então o UDP faz isso apenas colocando-o em camadas sobre o IP.) Se um datagrama é dividido em dois pacotes, o protocolo IP o remontará para o protocolo UDP, para que você verá os dados completos.
fonte
Você não pode ter certeza de que eles realmente chegam fisicamente de uma só vez. As camadas de vínculo de dados abaixo de TCP / UDP podem dividir seu pacote, se desejar. Especialmente se você enviar dados pela Internet ou por qualquer rede fora do seu controle, é difícil prever isso.
Mas não importa se os dados chegam em um pacote ou em vários pacotes no receptor. O sistema operacional deve abstrair a concatenação desses pacotes; portanto, para o seu aplicativo, ainda parece que tudo chegou ao mesmo tempo. Portanto, a menos que você seja um hacker de kernel, na maioria dos casos você não precisa se preocupar se esses dados são transferidos em um ou muitos pacotes.
Para o UDP, o sistema operacional também fará alguma abstração, portanto, o aplicativo que recebe os dados não precisa saber em quantos pacotes os dados foram transmitidos. Mas a diferença para o TCP é que não há garantia de que os dados realmente cheguem. Também é possível que os dados sejam divididos em vários pacotes, e alguns deles chegam e outros não. De qualquer forma, para o aplicativo de recebimento, parece um fluxo de dados, independentemente de estar completo ou não.
fonte
Exemplos. Blocos de caracteres contíguos correspondem a chamadas send ():
TCP:
Todos os dados enviados são recebidos em ordem, mas não necessariamente nos mesmos blocos.
UDP:
Os dados não estão necessariamente na mesma ordem e nem sempre são recebidos, mas as mensagens são preservadas na sua totalidade.
fonte
Não, o TCP é um protocolo de fluxo, mantém os dados em ordem, mas não os agrupa por mensagem. Por outro lado, o UDP é orientado a mensagens, mas não confiável. O SCTP tem o melhor dos dois mundos, mas não é nativamente utilizável porque os NATs quebram a Internet.
fonte
Há alguma garantia de que, se você enviar 20 bytes no início de um fluxo TCP, ele não chegará como duas partes de 10 bytes. Isso ocorre porque a pilha TCP não envia segmentos tão pequenos: existe um tamanho mínimo de MTU. No entanto, se o envio estiver em qualquer lugar no meio de um fluxo, todas as apostas serão desativadas. Pode ser que sua pilha de protocolos use 10 bytes dos dados para preencher um segmento e enviá-lo e, em seguida, os próximos dez bytes vão para outro segmento.
Sua pilha de protocolos divide os dados em pedaços e os coloca em uma fila. Os tamanhos dos pedaços são baseados no caminho MTU. Se você executar uma operação de envio e ainda houver dados na fila pendentes, a pilha de protocolos normalmente examinará o segmento que está no final da fila e verificará se há espaço nesse segmento para adicionar mais dados. A sala pode ter o tamanho de um byte, portanto, mesmo um envio de dois bytes pode ser dividido em dois.
Por outro lado, a segmentação de dados significa que pode haver leituras parciais. Uma operação de recebimento pode potencialmente ativar e obter dados quando chega apenas um segmento. Na API de soquetes amplamente implementada, uma chamada de recebimento pode solicitar 20 bytes, mas pode retornar com 10. Obviamente, uma camada de buffer pode ser construída nela, bloqueando até que 20 bytes sejam recebidos ou a conexão quebre. No mundo POSIX, essa API pode ser o fluxo de E / S padrão: você pode usar
fdopen
um descritor de soquete para obter umFILE *
fluxo e usáfread
-lo para preencher um buffer, de modo que a solicitação completa seja satisfeita com o número deread
chamadas necessárias. .Os datagramas UDP enquadram os dados. Cada chamada de envio gera um datagrama (mas veja abaixo sobre rolhas). O outro lado recebe um datagrama completo (e, na API do soquete, ele deve especificar um buffer grande o suficiente para retê-lo, caso contrário, o datagrama será truncado). Os datagramas grandes são fragmentados pela fragmentação de IP e são remontados de forma transparente aos aplicativos. Se algum fragmento estiver ausente, o datagrama inteiro será perdido; não há como ler dados parciais nessa situação.
Existem extensões para a interface, permitindo que várias operações especifiquem um único datagrama. No Linux, um soquete pode ser "arrolhado" (impedido de enviar). Enquanto estiver arrolhado, os dados gravados são reunidos em uma única unidade. Então, quando o soquete é "desarrolhado", um único datagrama pode ser enviado.
fonte