简体   繁体   English

在 MacOS 上获取套接字对等 IP 地址的正确方法

[英]Correct way to get a socket's peer IP address on MacOS

I'm trying this simple code, to get the client's IP address.我正在尝试这个简单的代码,以获取客户端的 IP 地址。 It works nice on FreeBSD, but strangely returns zeroes on MacOS.它在 FreeBSD 上运行良好,但在 MacOS 上奇怪地返回零。 I'm confused and can't understand what's wrong.我很困惑,无法理解出了什么问题。

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

int main() {
    int s, c;
    socklen_t len;
    struct sockaddr_in saddr, caddr;

    if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        printf("socket()\n"); exit(1);
    }
    
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port = htons(9090);

    if ((bind(s, (struct sockaddr *)&saddr, sizeof(saddr))) != 0) {
        printf("bind()\n"); exit(1);
    }

    if ((listen(s, 5)) != 0) {
        printf("listen()\n"); exit(1);
    }

    if ((c = accept(s, (struct sockaddr *)&caddr, &len)) < 0) {
        printf("accept()\n"); exit(0);
    }

    char ipstr[INET6_ADDRSTRLEN];
    inet_ntop(AF_INET, &caddr.sin_addr, ipstr, len);
    
    printf("Client IP address: [%s:%d]\n", ipstr, ntohs(caddr.sin_port));

    close(c);  close(s);

    return 0;
}

On FreeBSD:在 FreeBSD 上:

Client IP address: [127.0.0.1:17225]

On MacOS:在 MacOS 上:

Client IP address: [0.0.0.0:0]

You must initialize len before calling accept .必须在调用accept之前初始化len It tells accept the size of the structure passed to it:它告诉accept传递给它的结构的大小:

len = sizeof caddr;
if ((c = accept(s, (struct sockaddr *)&caddr, &len)) < 0) { ... }

If it's not initialized it will have an indeterminate (read: garbage) value which could lead to undefined behavior .如果它没有初始化,它将有一个不确定的(读取:垃圾)值,这可能会导致未定义的行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM