【问题标题】:C socket get IP address from filedescriptor returned from acceptC套接字从accept返回的filedescriptor获取IP地址
【发布时间】:2013-12-26 15:32:55
【问题描述】:

我知道这个问题似乎很典型并且多次回答,但我认为如果您阅读详细信息,它并不常见(我没有找到)。

关键是我正在用 c 开发一个 unix 服务,它打开一个套接字并等待连接,当我有一个连接时,我 创建一个新进程来处理它,因此可以同时打开多个连接

int newfd = accept(sockfd, (struct sockaddr *)&clientaddr, (socklen_t*)&clientaddr_size);

稍后(在其他一些方法之后和内部和代码)子进程将连接信息保存到 BBDD,我还需要,准确地说时刻获取打开正在处理的连接的 IP 地址

因为可以同时有多个连接,并且我传递给accept方法的变量struct sockaddr_in clientaddr所有进程共享的我不确定以后通过这种方式获取 IP 地址信息是否是个好主意,因为那时我可以从另一个打开的连接中获取 IP 地址

我希望能够从我从接受方法获得的文件描述符int newfd 访问 IP 地址(返回的整数)。可能吗?还是我误解了文件描述符函数?

【问题讨论】:

  • 谢谢@alk 我看到的很相似,虽然(肯定是因为我的英语),我不需要绑定地址,我需要客户地址。现在我看到了类似的方法,但是使用 getpeername() 方法:)
  • 啊,我明白了。因此,您可能想为自己的问题添加答案,甚至接受它。
  • 好的。这个是@JosephQuinsey,既平等又简单。抱歉我之前没找到...

标签: c sockets unix fork file-descriptor


【解决方案1】:

好的。感谢@alk 和@rileyberton,我找到了正确的使用方法,getpeername

int sockfd;

void main(void) {
    //[...]
    struct sockaddr_in clientaddr;
    socklen_t clientaddr_size = sizeof(clientaddr);
    int newfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_size);
    //fork() and other code
    foo(newfd);
    //[...]
}
void foo(int newfd) {
    //[...]
    struct sockaddr_in addr;
    socklen_t addr_size = sizeof(struct sockaddr_in);
    int res = getpeername(newfd, (struct sockaddr *)&addr, &addr_size);
    char *clientip = new char[20];
    strcpy(clientip, inet_ntoa(addr.sin_addr));
    //[...]
}

因此,现在在不同的进程中,我可以获取发起连接的客户端的 IP 地址(在“字符串”clientip 中),该连接仅携带通过接受方法获得的文件描述符 newfd

【讨论】:

  • 不要将addr_size 声明为int,而是声明为socklen_t。在对getpeername() 的调用中将int* 转换为socklen_t* 可以隐藏可能的问题,以防socklen_t 的大小与int 的大小不同。对accept() 的调用也是如此。
  • 完成!而且我在对 accept() 方法的调用中更改了它。非常感谢您的建议:)
【解决方案2】:

您将使用getsockname() (http://linux.die.net/man/2/getsockname) 来获取绑定套接字的 IP。

之前也回答过,这里:C - Public IP from file descriptor

【讨论】:

  • 谢谢@rileyberton,它对我有用的正确方法是 getpeername() (linux.die.net/man/2/getpeername) 我可以看到这篇文章非常相似,但由于进程之间的大量讨论有点混淆了这个问题:P
  • 绑定的socket的IP地址不是他要求的。阅读问题。
【解决方案3】:

Statefull 连接由两个端点 Peer(address:port)My(address:port) 唯一标识。 getpeername() 和 getsockname() 都需要获取此信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多