#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd:已連接的流式套接字描述符 (SOCK_STREAM)。addr:輸出緩衝區指針,指向 struct sockaddr (或 sockaddr_in, sockaddr_in6),接收對端地址信息。addrlen:輸入輸出參數。調用前設為緩衝區大小 (sizeof(struct sockaddr_in));返回時為實際寫入地址結構大小。0:成功。-1:失敗,設置 errno (如 ENOTCONN 未連接,EINVAL 參數無效)。accept() 返回的 connFd 獲取客戶端 IP/端口 (雖 accept 已提供,但 getpeername 通用於任何已連接套接字)。
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void print_peer(int sockfd)
{
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
if (getpeername(sockfd, (struct sockaddr *)&addr, &len) == 0)
{
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip));
printf("對端: %s:%d\n", ip, ntohs(addr.sin_port));
}
else
{
perror("getpeername");
}
}
獲得 struct sockaddr_in 後,可用:
inet_ntop() / inet_ntoa():IP 轉字串。gethostbyaddr():反向 DNS 解析主機名 (過時,建議 getnameinfo())。**無法獲取**:對端用戶帳號 (需 ident 協議 RFC 1413,已基本廢棄)。
getpeername() 是「已連接套接字」查詢對端身份的標準途徑,簡單高效,配合地址轉換函數即可完成網絡實體識別。