Como a função de API Accept () do soquete funciona?

126

A API do soquete é o padrão de fato para as comunicações TCP / IP e UDP / IP (ou seja, o código de rede como o conhecemos). No entanto, uma de suas principais funções accept()é um pouco mágica.

Para emprestar uma definição semi-formal:

accept () é usado no lado do servidor. Ele aceita uma tentativa de entrada recebida para criar uma nova conexão TCP do cliente remoto e cria um novo soquete associado ao par de endereços de soquete dessa conexão.

Em outras palavras, acceptretorna um novo soquete através do qual o servidor pode se comunicar com o cliente recém-conectado. O soquete antigo (no qual acceptfoi chamado) permanece aberto, na mesma porta, ouvindo novas conexões.

Como acceptfunciona? Como é implementado? Há muita confusão sobre esse tópico. Muitas pessoas afirmam que aceitar abre uma nova porta e você se comunica com o cliente através dela. Mas isso obviamente não é verdade, pois nenhuma porta nova é aberta. Você realmente pode se comunicar através da mesma porta com clientes diferentes, mas como? Quando vários encadeamentos chamam recvna mesma porta, como os dados sabem para onde ir?

Eu acho que é algo semelhante ao endereço do cliente associado a um descritor de soquete, e sempre que os dados chegam, recveles são roteados para o soquete correto, mas não tenho certeza.

Seria ótimo obter uma explicação completa do funcionamento interno desse mecanismo.

Eli Bendersky
fonte
2
portanto, para cada solicitação do cliente, uma nova conexão de soquete no final do servidor é aberta. O servidor deve estar aberto às 80 sempre para ouvir as chamadas recebidas. Se receber uma chamada, cria imediatamente um novo soquete com as quatro tuplas, conforme mencionado abaixo, que fará uma conexão TCP entre o cliente e o servidor. Meu entendimento está correto?
brain storm
1
Esta é uma questão muito fundamental e eu foi recentemente testado sobre isso em uma entrevista: stackoverflow.com/questions/24871827/... Se você tem algum comentário sobre isso, por favor poste
tempestade cerebral
@brainstorm Somente se você ignorar completamente a existência do HTTP keep-alive.
Marquês de Lorne

Respostas:

140

Sua confusão reside em pensar que um soquete é identificado pelo IP do servidor: Porta do servidor. Na realidade, os soquetes são identificados exclusivamente por um quarteto de informações:

Client IP : Client Port e Server IP : Server Port

Portanto, embora o IP do servidor e a porta do servidor sejam constantes em todas as conexões aceitas, as informações do lado do cliente são o que permite acompanhar onde tudo está indo.

Exemplo para esclarecer as coisas:

Digamos que temos um servidor 192.168.1.1:80e dois clientes, 10.0.0.1e 10.0.0.2.

10.0.0.1abre uma conexão na porta local 1234e se conecta ao servidor. Agora o servidor tem um soquete identificado da seguinte maneira:

10.0.0.1:1234 - 192.168.1.1:80  

Agora 10.0.0.2abre uma conexão na porta local 5678e se conecta ao servidor. Agora o servidor tem dois soquetes identificados da seguinte maneira:

10.0.0.1:1234 - 192.168.1.1:80  
10.0.0.2:5678 - 192.168.1.1:80
17 de 26
fonte
3
Não conheço os detalhes da implementação (que provavelmente variam de plataforma para plataforma), apenas sei que conceitualmente os soquetes são identificados pelo quarteto de informações que descrevi.
17 de 26
3
Você tem alguma referência sobre isso?
Q8
3
Pergunta aleatória: O que acontece se o NAT estiver sendo usado e dois clientes na mesma rede tentarem usar a mesma porta local ao se conectar ao servidor? Por exemplo, se 10.0.0.1 e 10.0.0.2 estiverem conectados a um roteador com um IP externo 192.168.0.1, portanto, o servidor em 192.168.1.1 verá duas conexões a partir de 192.168.0.1. O que acontece nesse caso se, por algum acaso do gerador de números aleatórios, 10.0.0.1 e 10.0.0.2 escolherem a mesma porta local?
Aroth 29/03/12
4
O suporte NAT no roteador cuida dos detalhes lá. O tráfego de rede está passando por duas conexões - cliente para roteador e roteador para servidor. O roteador faz as conexões de saída em duas portas diferentes 192.168.0.1:1234 e 192.168.0.1:5678. O tráfego recebido é então redirecionado pelo roteador para o cliente correto.
17 de 26
3
Se um soquete é identificado pelo quarteto, quais são as informações do quarteto de um soquete de audição?
Eric Zheng
74

Apenas para adicionar à resposta dada pelo usuário "17 de 26"

Na verdade, o soquete consiste em 5 tuplas - (ip de origem, porta de origem, ip de destino, porta de destino, protocolo). Aqui, o protocolo pode TCP ou UDP ou qualquer protocolo da camada de transporte. Este protocolo é identificado no pacote no campo 'protocol' no datagrama IP.

Portanto, é possível ter aplicativos diferentes no servidor se comunicando com o mesmo cliente exatamente nas mesmas quatro tuplas, mas diferentes no campo do protocolo. Por exemplo

Apache no lado do servidor falando (server1.com:880-client1:1234 no TCP) e World of Warcraft falando (server1.com:880-client1:1234 no UDP)

Tanto o cliente quanto o servidor tratam disso como o campo de protocolo no pacote IP nos dois casos é diferente, mesmo que todos os outros quatro campos sejam iguais.

Methos
fonte
13

O que me confundiu quando aprendi isso foi que os termos sockete portsugerem que eles são algo físico, quando na verdade são apenas estruturas de dados que o kernel usa para abstrair os detalhes da rede.

Como tal, as estruturas de dados são implementadas para poder separar conexões de diferentes clientes. Quanto à maneira como são implementadas, a resposta é a.) Não importa, o objetivo da API de sockets é precisamente que a implementação não importe ou b.) Basta dar uma olhada. Além dos livros altamente recomendados da Stevens, que fornecem uma descrição detalhada de uma implementação, consulte a fonte no Linux ou Solaris ou em um dos BSDs.

a2800276
fonte
Sim, a maior parte da terminologia de rede está apenas atribuindo nomes a determinadas coleções de bits e a decisões tomadas com base em seus valores ("identificador de protocolo", "roteamento", "ligação", "soquete" etc.). Todo o hardware da sua placa de rede é projetado para receber um fluxo de bits. O que acontece com eles em relação aos programas no seu computador é decidido pelo driver e pelo sistema operacional. Poderíamos se livrar de tudo isso amanhã terminologia se quiséssemos, mas o princípio de entregar um fluxo de bits parece fundamental ...
masterxilo
-1

Como o outro cara disse, um soquete é identificado exclusivamente por quatro tuplas (IP do cliente, Porta do cliente, IP do servidor, Porta do servidor).

O processo do servidor em execução no IP do servidor mantém um banco de dados (o que significa que não me importo com o tipo de estrutura de tabela / lista / árvore / matriz / dados mágicos que ele usa) de soquetes ativos e escuta na porta do servidor. Quando recebe uma mensagem (através da pilha TCP / IP do servidor), verifica o IP e a porta do cliente no banco de dados. Se o IP do cliente e a porta do cliente forem encontrados em uma entrada do banco de dados, a mensagem será entregue a um manipulador existente; caso contrário, uma nova entrada de banco de dados será criada e um novo manipulador será gerado para lidar com esse soquete.

Nos primeiros dias do ARPAnet, determinados protocolos (FTP para um) escutavam uma porta especificada para solicitações de conexão e respondiam com uma porta de transferência. Comunicações adicionais para essa conexão passariam pela porta de transferência. Isso foi feito para melhorar o desempenho por pacote: os computadores eram várias ordens de magnitude mais lentas naqueles dias.


fonte
você pode elaborar sobre a parte 'porta de transferência'?
Eli Bendersky
1
Essa é uma descrição de algum protocolo pré-TCP ou simplificada demais. Um cliente que tenta se conectar a um soquete de escuta envia um pacote especial para estabelecer a conexão (conjunto de bits SYN). Há uma distinção clara entre um pacote que cria um novo soquete e outro que usa um soquete existente.
John M
... envia um pacote especial para estabelecer a conexão (conjunto de bits SYN). O que (como eu o entendo) faz com que a pilha de protocolos o entregue ao ouvinte '(se houver), e é por isso que pode haver apenas uma porta de escuta por combinação de endereço / porta / protocolo. Não tenho certeza se isso está na especificação ou apenas na convenção de implementação.
Peter Wone
1
O segundo parágrafo não descreve corretamente o que acontece na camada TCP ou dentro de um processo do servidor. Os processos do servidor não precisam manter estruturas de dados de soquetes de qualquer tipo ou verificar os pares de IP: porta de entrada em relação a qualquer coisa. É para isso que servem as tomadas. O FTP usa uma porta separada para dados, não para todas as 'comunicações adicionais', e chapéus feitos para simplificar o protocolo, não por razões de desempenho. Usar uma nova porta sem melhorar o desempenho de qualquer forma.
Marquês de Lorne
"mantém um banco de dados (o que significa que eu não me importo com o tipo de estrutura de tabela / lista / árvore / matriz / dados mágicos que ele usa)" :) Eu costumo chamar isso de "Tabela" (ou talvez "Gráfico" ou "Árvore de decisão" ) "Banco de dados" sugere alguma implementação para mim.
Masterxilo # 13/18