Как создать TCP-сокет для подключения с помощью C к предопределенному порту

StackOverflow https://stackoverflow.com/questions/204169

  •  03-07-2019
  •  | 
  •  

Вопрос

У меня очень простой вопрос.Я хочу проверить, используется ли конкретный порт в данный момент или нет.Для этого я хочу привязать сокет TCP к порту: если в соединении отказано, это означает, что порт используется, а если нет, то это означает, что порт свободен.

Может кто-нибудь сказать мне, как я могу написать код сокета TCP на C?Я на платформе Solaris.

Я знаю, что это очень просто.Но я ценю вашу помощь.Заранее спасибо.

Это было полезно?

Решение

Вызов функции привязки вернет -1 в случае ошибки.Это включает в себя случай, когда адрес уже используется.

#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);
}

Другие советы

Это немного зависит от того, что именно вы пытаетесь проверить.

С использованием bind() способ, предложенный joelc, сообщит вам, открыт ли порт любой интерфейс на вашем компьютере.Хотя для большей тщательности вам следует проверять не только возвращаемое значение из bind(), но и проверка errno == EADDRINUSE.

то есть.(модификация кода joelc)


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

Изменив адрес, используемый в строке:например.


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

... вы можете проверить, доступен ли порт на определенном интерфейсе.

Имейте в виду, однако, что это не идеальный тест состояния порта.Если другой процесс открыл порт и был завершен до того, как он корректно закрыл порт (т.перед звонком close() на розетке), то вы обычно получите то же самое EADDRINUSE ошибка.(в зависимости от того, установлена ​​ли в сокете опция SO_REUSEADDR)

(Примечание:если ваше тестовое приложение не работает с достаточными привилегиями, вы не сможете привязать() к любым портам ниже 1024)

Как предложил Anonymous, вы также можете взглянуть на netstat.Это даст вам всю ту же информацию, которую вы можете получить, неоднократно звоня bind() гораздо быстрее и без каких-либо побочных эффектов (например, ему не нужно фактически привязываться к портам, что сделало бы их непригодными для использования другими процессами).Просто звоню netstat -a --numeric-ports -t и анализ результатов должен дать вам все, что вам нужно.

Однако комментарий к предложению moogs: вызов telnet на каждом порту сообщит вам только о том, прослушивает ли сокет этот порт, а не о том, открыт ли он на самом деле.

Вы просто хотите проверить, используется ли конкретный порт в данный момент?(и на самом деле не нужно делать программу).Если да, вы можете использовать telnet:

хост-порт телнета

Если соединение не удалось, оно не используется.Если он подключается и ждет вашего ввода, значит, он используется :)

Возможно, вы захотите посмотреть исходный код netstat.Я считаю, что в Solaris также есть netstat.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top