从Linux中的socket编程中侦听和接受的连接中提取IP

时间:2010-01-20 19:59:10

标签: c network-programming sockets ip

在以下代码中,我想在接受传入连接后提取已连接客户端的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 个答案:

答案 0 :(得分:11)

cli_addr成功返回后,您的accept()已包含已连接客户端的IP地址和端口,格式与serv_addr变量相同。使用inet_ntop将IP转换为字符串。

答案 1 :(得分:6)

答案 2 :(得分:2)

我认为不需要getpeername() - cli_addr来电已将客户地址填入accept()

您只需使用inet_ntop()getnameinfo()gethostbyaddr()打印或获取更多信息。

答案 3 :(得分:1)

您可以按照以下示例:

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

答案 4 :(得分:1)

API在手册页中有描述。您可以从控制台浏览它们,从man socket开始,并按照man getpeername的引用或使用Konqueror,如果您要求#socket地址,则可以使用链接很好地呈现它。就我在Kubuntu的情况而言,有必要安装manpages-dev包。