Pergunta

Estou escrevendo um teste UDP cliente / servidor e eu quero fazê-lo através do firewall. Supostamente tudo que eu preciso fazer é ter ambos os lados enviar para o IP e servidor correto. Conseguir um IP não é um problema, mas como faço para ter o cliente escolher uma porta livre aleatória e relatá-lo para o usuário? Eu finalmente iria querer isso para se conectar a um servidor de casamenteiro, mas agora eu preciso de um protótipo de trabalho simples e eu gostaria de cout o número da porta para que meu amigo / testador pode me enviar o # via IM para que possamos testar.

Como faço para obter o número da porta? Desculpe pelo longo desc. Eu observo as pessoas dizem-me para não fazer o que eu estou perguntando quando eu não dou um desc: (

Foi útil?

Solução

Para usar o termo altamente técnico, este é realmente um problema bastante icky ou mesmo um par de problemas nojento. Dependendo da configuração do firewall, que normalmente vai permitir respostas de outro terminal no ponto de extremidade IP como o pedido veio. Então ... se você amigo recebe o datagrama UDP usando algo parecido com a chamada de sistema recvfrom(), o parâmetro endereço receberá as informações de endpoint IP para responder a. Então a outra extremidade deve ser capaz de responder com um sendto() usando as mesmas informações de endereçamento. Algo como:

/* initiator */
struct sockaddr_in hisaddr;
memset(&hisaddr, 0, sizeof(hisaddr));
hisaddr.sin_addr.s_addr = htonl(target_ip);
hisaddr.sin_port = htons(target_port);
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&hisaddr, sizeof(hisaddr));

/* receiver */
struct sockaddr_in peeraddr;
socklen_t peer_sz = sizeof(peeraddr);
recvfrom(sd, buf_ptr, buf_sz, 0, (struct sockaddr*)&peeraddr, &peer_sz);
/* build response */
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&peeraddr, peer_sz);

O peeraddr do outro lado será a sua externo endereço ou, mais corretamente, o endereço IP do seu firewall e o número da porta que ele escolheu para usar. O número da porta que você especificar em seu código pode ser completamente diferente do que a porta que seu amigo teria que enviar dados. Em última análise, pode não importa o que porta você optar por usar uma vez que o firewall pode ser o envio e recebimento em uma porta totalmente diferente - é isso que Network Address Translation é tudo. Eu recomendo a leitura RFC3235 para algumas dicas sobre como superar esse obstáculo.

A melhor abordagem IMHO é:

  1. Deixe o OS escolher uma porta por qualquer chamando bind() com um zero número de porta ou pular o ligamento completamente
  2. Tendo o cliente recebe as informações de endereço do socket layer (por exemplo, nofollow, os quinto e sexto argumentos para recvfrom() )
  3. O cliente envia a resposta para o ponto final recuperado na etapa anterior
  4. ajustar as configurações de firewall até as etapas de trabalho anterior

É claro, toda a magia está na última etapa. Se você pode desativar NAT ou garantir que o firewall não vai portas de switch, então pregar para baixo um número de porta e bind-ing a ele vai funcionar tão bem. Você pode querer dar uma olhada em %WINDIR%\system32\drivers\etc\services (ou /etc/services dependendo de sua inclinação OS) para ter uma idéia do que os números de porta são reservados ou geralmente em uso.

Outras dicas

De um modo geral - você - como o desenvolvedor - escolha a porta. Você pode configurar seu aplicativo para ler a porta de uma entrada de arquivo de configuração ou usuário - mas nenhum firewall mágica vai lhe dizer o que porta a utilizar ...

Se eu estou entendendo sua pergunta, eu não tenho certeza que há uma maneira de fazer o que você quer através de programação (e mesmo se houver, eu não acho que é o caminho certo). Eu acho que você precisa encontrar uma porta que não está em uso na máquina do servidor (e talvez uma diferente ou a mesma porta na máquina do cliente, se a comunicação é bidirecional), e que porta deve ser capaz de passar através de seu firewall . Eu assumo desde que você diz "a obtenção de um IP não é um problema", você já configurou o firewall para encaminhar algumas ou todas as portas a um computador específico dentro do firewall? Se assim for, o porto que você procura é um dos que você encaminhadas. Você pode escolher apenas arbitrária, contanto que nenhum outro serviço está sendo executado nessa porta. Portas abaixo de 1024 são reservados, então você provavelmente vai querer escolher um número maior do que isso. Você pode usar uma ferramenta portscanning simples, como nmap para ver quais os serviços que estão em execução no seu computador sobre quais portas e escolher um diferente 1. Note-se que nmap pode ser enganado por firewalls e várias regras bind quando soquetes são criados.

Eu acho que você é melhor fora de escolher uma porta fixa em vez de depender do número de porta aleatório escolhido pelo O / S.

Se você usar uma porta aleatória você teria que alterar as configurações do firewall cada vez que você executar o programa.

Se você estiver usando WINSOCK verificar este link: http://msdn.microsoft.com/en-us /library/aa280717(VS.60).aspx Basicamente, você tem 2 opções definir a porta a 0 e deixar o sistema atribuir-lhe um ou escolheu uma tentativa aleatória para abrir o socket se ele não funcionar, tente outra (não se esqueça de orientar clara de portas reservadas)

bind () da tomada antes de enviar os seus dados. Especifique a porta 0 para ligar (), e o sistema operacional irá escolher uma porta não utilizada para você. Você pode então usar getsockname () para descobrir qual porta wsa escolhido.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top