Pergunta

Eu tenho uma pergunta muito simples. Eu quero testar se uma determinada porta está atualmente em uso ou não. Para isso, eu quero vincular um soquete TCP para a porta, se a conexão for recusada significa que a porta está em uso e se não significa que a porta esteja livre.

Alguém por favor pode me dizer como eu posso escrever o código de soquete TCP em C? Estou em uma plataforma Solaris.

Eu sei que é muito básico. Mas eu aprecio sua ajuda. Agradecemos antecipadamente.

Foi útil?

Solução

A chamada para a função de ligação irá retornar -1 se houver um erro. Isto inclui o caso em que o endereço já está em uso.

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 12345

int main()
{
  struct sockaddr_in addr;
  int fd;

  fd = socket(AF_INET, SOCK_STREAM, 0);
  if(fd == -1)
  {
      printf("Error opening socket\n");
      return -1;
  }

  addr.sin_port = htons(PORT);
  addr.sin_addr.s_addr = 0;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_family = AF_INET;

  if(bind(fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in) ) == -1)
  {
      printf("Error binding socket\n");
      return -1;
  }

  printf("Successfully bound to port %u\n", PORT);
}

Outras dicas

Depende um pouco sobre o que exatamente você está tentando teste.

Usando bind() da maneira que joelc sugeriu vai dizer se a porta está aberta no qualquer interface na sua máquina. Apesar de ser completo, você deve não só estar verificando o valor de retorno de bind(), mas também verificar errno == EADDRINUSE.

ie. (Modificação do código do joelc)


if(bind(socket, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) == -1)
{
    if( errno == EADDRINUSE )
    {
        // handle port already open case
    }
    else
    {
        // handle other errors
    }
}

Ao alterar o endereço usado na linha:. Ex


    sin.sin_addr.s_addr = inet_addr("192.168.1.1");

... você pode testar se uma porta está disponível em uma interface específica.

Lembre-se que este não é um teste perfeito para Estado do porto. Se outro processo tinha a porta aberta e foi encerrado antes que graciosamente fechou a porta (ie. Antes de chamar close() no soquete), em seguida, normalmente você vai obter o mesmo erro EADDRINUSE. (Dependendo se a opção SO_REUSEADDR tinha sido definido no soquete)

(nota: a menos que seu aplicativo de teste está sendo executado com privilégios suficientes você não será capaz de bind () para todas as portas abaixo de 1024)

Como Anonymous sugerido, você pode também ter um olhar para netstat. Isto lhe dará todas as mesmas informações que você pode obter por várias vezes chamar bind() muito mais rapidamente e sem nenhum dos efeitos colaterais (como ele não tem de se ligar realmente para os portos, o que as tornam inutilizáveis ??para quaisquer outros processos ). Apenas chamando netstat -a --numeric-ports -t e analisar a saída deve dar-lhe tudo o que você está depois.

Um comentário sobre moogs sugestão embora - chamando telnet em cada porta só irá dizer-lhe se um soquete está escutando nessa porta -. Não se é realmente aberto

Você só quer testar se a porta específica está atualmente em uso? (E realmente não precisa fazer um programa). Se assim for, você pode usar telnet:

porta do host telnet

Se a conexão falhar, ele não está em uso. Se ele se conecta e espera para entrada de você, ele está em uso:)

Você pode querer olhar para o código-fonte do netstat. Eu acredito que há um netstat no Solaris também.

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