【问题标题】:Can not print out specific address of server socket with getsockname()无法使用 getsockname() 打印出服务器套接字的特定地址
【发布时间】:2018-10-14 22:34:48
【问题描述】:

我使用getpeername() 和getsockname() 在服务器端打印出客户端socket 和服务器socket 的IP 地址。但是,只指定了客户端套接字的IP地址,而服务器套接字的IP地址是0.0.0.0。我该如何解决这个问题,以便可以指定服务器套接字的 IP 地址?

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include "Practical.h"

 static const int MAXPENDING = 5; // Maximum outstanding connection requests

  int main(int argc, char *argv[]) {

  if (argc != 2) // Test for correct number of arguments
    DieWithUserMessage("Parameter(s)", "<Server Port>");

  in_port_t servPort = atoi(argv[1]); // First arg: local port

 // Create socket for incoming connections
  int servSock; // Socket descriptor for server
 if ((servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    DieWithSystemMessage("socket() failed");

 // Construct local address structure
 struct sockaddr_in servAddr; // Local address
 memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure
 servAddr.sin_family = AF_INET; // IPv4 address family
 servAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
 servAddr.sin_port = htons(servPort); // Local port

 // Bind to the local address
 if (bind(servSock, (struct sockaddr*) &servAddr, sizeof(servAddr)) < 0)
    DieWithSystemMessage("bind() failed");

 // Mark the socket so it will listen for incoming connections
 if (listen(servSock, MAXPENDING) < 0)
    DieWithSystemMessage("listen() failed");

 for (;;) { // Run forever
    struct sockaddr_in clntAddr; // Client address
    // Set length of client address structure (in-out parameter)
    socklen_t clntAddrLen = sizeof(clntAddr);
    // Wait for a client to connect
    int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
    if (clntSock < 0)
       DieWithSystemMessage("accept() failed"); 

   // clntSock is connected to a client!

   char clntName[INET_ADDRSTRLEN]; // String to contain client address
   if (inet_ntop(AF_INET, &clntAddr.sin_addr.s_addr, clntName, sizeof(clntName)) != NULL)
       printf("Handling client %s/%d\n", clntName, ntohs(clntAddr.sin_port));
   else
       puts("Unable to get client address");
   getpeername(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
   inet_ntop(AF_INET, &clntAddr.sin_addr.s_addr, clntName, sizeof(clntName));
   printf("After accept(): The client IP address is: %s and client port is: %u \n", clntName, ntohs(clntAddr.sin_port));

   char serverIP[INET_ADDRSTRLEN];
   socklen_t servlen = sizeof(servAddr);
   inet_ntop(AF_INET, &servAddr.sin_addr, serverIP, sizeof(serverIP));
   getsockname(servSock, (struct sockaddr *) &servAddr, &servlen);
   printf("After accept(): The server IP address is %s and server port is %u \n", serverIP, servPort);

   HandleTCPClient(clntSock);
 }
 // NOT REACHED
}

输出是:

客户端socket的IP地址:10.0.2.15

服务器套接字的IP地址:0.0.0.0

那么,我怎样才能使服务器套接字的 IP 地址具体为 10.0.2.15 而不是 0.0.0.0

【问题讨论】:

    标签: c sockets


    【解决方案1】:
        int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
    
       getpeername(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
    

    您必须使用clntSock 致电getpeername()getsockname() 同上。

    当使用无效套接字调用时,这两个函数都可能失败(这可能发生在您的程序中)并返回随机数据。

    【讨论】:

    • 打印出客户端 IP 地址的 getpeername() 仍然可以正常工作。但我的麻烦在于打印输出服务器IP地址的getsockname(),因为它无法按我的预期打印特定的IP地址
    • getsockname() 调用也使用了错误的套接字 (servSock)。
    • 另外,不需要在显示的代码中调用getpeername(),因为它会返回与accept() 已经为远程对等方提供的相同的sockaddr_in 数据。
    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    相关资源
    最近更新 更多