تابع ()getpeername

این تابع برای پیدا کردن آدرس سوی دیگر connection یک سوکت استفاده می شود.

#include <sys/socket.h>
 
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

مثال: مانند خواندن آدرس کلاینت بعد از تابع ()accept منتها این بار نه از پارامتر های تابع ()accept بلکه با تابع ()getpeername

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
 
#define PORT "3450"
#define BACKLOG 120
 
int main()
{
    int status, sockfd, clientfd, sockopt;
    struct addrinfo hints, *res, *rp;
 
    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_PASSIVE;
    hints.ai_family = AF_INET6;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = 0;
 
    status = getaddrinfo(NULL, PORT, &hints, &res);
    if (status != 0) {
        fprintf(stderr, "getaddrinfo() error: %s\n", 
                gai_strerror(status));
        exit(EXIT_FAILURE);
    }
 
    for (rp = res; rp != NULL; rp = rp->ai_next) {
        sockfd = socket(rp->ai_family, rp->ai_socktype, 
                            rp->ai_protocol);
        if (sockfd == -1) {
            perror("socket() error");
            continue;
        }
 
        sockopt = 1;
        status = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 
                            &sockopt, sizeof(sockopt));
        if (status == -1) {
            perror("setsockopt() error");
            exit(EXIT_FAILURE);
        }
 
        sockopt = 0;
        status = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
                            &sockopt, sizeof(sockopt));
        if (status == -1) {
            perror("setsockopt() error");
            exit(EXIT_FAILURE);
        }
 
        status = bind(sockfd, rp->ai_addr, rp->ai_addrlen);
        if (status == -1) {
            perror("bind() error");
            continue;
        }
 
        break;
    }
    freeaddrinfo(res);
 
    if (rp == NULL) {
        fprintf(stderr, "Server: Failed to bind()\n");
        exit(EXIT_FAILURE);
    }
 
    status = listen(sockfd, BACKLOG);
    if (status == -1) {
        perror("listen() error");
        exit(EXIT_FAILURE);
    }
 
    printf("Server: waiting for connections...\n");
 
    clientfd = accept(sockfd, NULL, NULL);
    if (clientfd == -1) {
        perror("accept() error ");
        exit(EXIT_FAILURE);
    }
 
    struct sockaddr_storage peeraddr;
    socklen_t peeraddrlen = sizeof(peeraddr);
    status = getpeername(clientfd, (struct sockaddr*)&peeraddr, 
    			&peeraddrlen);
    if (status == -1) {
        perror("getpeername() error ");
        exit(EXIT_FAILURE);
    }
 
    void *addr;
    char *ipver;
    char ipstr[INET6_ADDRSTRLEN];
    struct sockaddr *sa = (struct sockaddr*)&peeraddr;
    if (sa->sa_family == AF_INET) {
        ipver = "IPv4";
        addr = &(((struct sockaddr_in *)sa)->sin_addr);
    } else {
        ipver = "IPv6";
        addr = &(((struct sockaddr_in6 *)sa)->sin6_addr);
    }
    inet_ntop(sa->sa_family, addr, ipstr, sizeof(ipstr));
    printf("Server: Got an %s connection from %s\n", ipver, ipstr);
 
    close(clientfd);
    close(sockfd);
    return 0;
}