Извлечение IP из соединения, которое слушает и принимает в сокет программирования в Linux в C - PullRequest
4 голосов
/ 20 января 2010

В следующем коде я хотел бы извлечь IP-адрес подключенного клиента после принятия входящего соединения. Что я должен сделать после accept(), чтобы добиться этого?

int sockfd, newsockfd, portno, clilen;
portno = 8090;
clilen = 0;
pthread_t serverIn;
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
    perror("ERROR opening socket");
}
bzero((char *) & serv_addr, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
serv_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr *) & serv_addr, sizeof (serv_addr)) < 0)
{
    perror("ERROR on binding");
}

listen(sockfd, 5);
clilen = sizeof (cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) & cli_addr, &clilen);

Ответы [ 5 ]

11 голосов
/ 20 января 2010

Ваш cli_addr уже содержит IP-адрес и порт подключенного клиента после успешного возврата accept() в том же формате, что и переменная serv_addr. Используйте inet_ntop для преобразования IP в строку.

2 голосов
/ 20 января 2010

Я думаю, getpeername() не требуется - адрес клиента уже введен в cli_addr с помощью вызова accept().

Вам нужно всего лишь использовать inet_ntop(), getnameinfo() или gethostbyaddr() для печати или получения дополнительной информации.

1 голос
/ 20 января 2010

API описан на страницах руководства. Вы можете либо просматривать их из консоли, начиная с man socket, и переходить по ссылкам на man getpeername, либо использовать Konqueror, который прекрасно отображает ссылки, если вы запрашиваете адрес #socket. В моем случае на Kubuntu нужно было установить пакет manpages-dev.

1 голос
/ 20 января 2010

Вы можете следовать этому примеру:

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

{
   int s;
   struct sockaddr_in peer;
   int peer_len;
   .
   .
   .
      /* We must put the length in a variable.              */
   peer_len = sizeof(peer);
      /* Ask getpeername to fill in peer's socket address.  */
   if (getpeername(s, &peer, &peer_len) == -1) {
      perror("getpeername() failed");
      return -1;
   }

      /* Print it. The IP address is often zero because     */
      /* sockets are seldom bound to a specific local       */
      /* interface.                                         */
   printf("Peer's IP address is: %s\n", inet_ntoa(peer.sin_addr));
   printf("Peer's port is: %d\n", (int) ntohs(peer.sin_port));
   .
   .
   .
}
...