8

我正在编写一个inetd 的克隆,我必须在其中运行一个服务器来打印连接到它的客户端的IP 和端口。

当我覆盖STDINSTDOUT使用套接字描述符时,我最初的解决方案是恢复sockaddr_in包含所需信息的结构。然而,这样做getsockname()会返回一个空结构,所有位都设置为 0。

知道我的方法有什么问题吗?我可以使用其他方法来恢复 IP/端口吗?

谢谢

4

3 回答 3

11

正如 R.. 指出的那样,您应该使用getpeername. 该函数都将getsockname文件描述符作为其第一个参数,而不是流指针 ( FILE *)。用于fileno(stdin)获取标准输入的文件描述符(或将其硬编码为STDIN_FILENO,因为它是常量)。

此外,getsocknameand的最后一个参数getpeername应该是指向 的指针socklen_t,而不是常量,您应该将 asockaddr_in用于 TCP/IP:

struct sockaddr_in peeraddr;
socklen_t peeraddrlen = sizeof(peeraddr);
getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen);

在此处查看完整示例。

于 2010-11-15T16:00:39.370 回答
3

使用getpeername. 我怀疑您的问题是getsockname返回您自己的(本地)套接字端的信息,这可能绑定到 0.0.0.0 (这意味着它可以接受来自任何接口的连接)。

编辑:我想我在阅读代码时发现了你的实际错误。这一行是错误的:

getsockname(stdin, &addr, sizeof(addr));

getsocknameandgetpeername函数将( socklen_t *a pointer ) 作为第三个参数,而不是 a size_t。编译器应该会告诉你这个错误,除非你忘记在getsockname. 此外,正如已经说过的,stdin是不正确的。尝试:

socklen_t len = sizeof addr;
getpeername(0, &addr, &len);

或(仅限 C99):

getpeername(0, &addr, (socklen_t[1]){sizeof addr});

您还应该检查返回值;如果你这样做了,你会看到它返回错误。

于 2010-11-15T15:57:24.317 回答
2

如果您需要远程客户端的这些信息,则必须调用getpeername()

于 2010-11-15T15:59:12.207 回答