我正在编写a clone of inetd,其中我必须运行一个服务器,打印连接到它的客户端的IP和端口。
当我用套接字描述符覆盖STDIN
和STDOUT
时,my initial solution执行此操作是为了恢复包含所需信息的sockaddr_in
结构。但是,对getsockname()
执行此操作会返回一个空结构,所有位都设置为0。
知道我的方法有什么问题吗?我还可以使用其他方法来恢复IP /端口吗?
由于
答案 0 :(得分:9)
正如R ..指出的那样,你应该使用getpeername
。函数和getsockname
都将文件描述符作为其第一个参数,而不是流指针(FILE *
)。使用fileno(stdin)
获取标准输入的文件描述符(或将其硬编码为STDIN_FILENO
,因为它是常量)。
此外,getsockname
和getpeername
的最后一个参数应该是指向socklen_t
的指针,而不是常量,您应该使用sockaddr_in
作为TCP / IP:
struct sockaddr_in peeraddr;
socklen_t peeraddrlen = sizeof(peeraddr);
getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen);
查看完整示例here。
答案 1 :(得分:3)
使用getpeername
。我怀疑你的问题是getsockname
正在返回套接字自身(本地)端的信息,这可能绑定到0.0.0.0(意味着它可以接受来自任何接口的连接)。
编辑:我认为我发现了您读取代码的实际错误。这条线错了:
getsockname(stdin, &addr, sizeof(addr));
getsockname
和getpeername
函数将socklen_t *
(一个指针)作为第三个参数,而不是size_t
。除非您忘记在getsockname
的原型中包含标题,否则编译器应该告诉您这个错误。此外,正如已经说过的那样,stdin
是不正确的。尝试:
socklen_t len = sizeof addr;
getpeername(0, &addr, &len);
或(仅限C99):
getpeername(0, &addr, (socklen_t[1]){sizeof addr});
您还应该检查返回值;如果你这样做,你会发现它返回了错误。
答案 2 :(得分:2)
如果您需要远程客户端的这些信息,则必须致电getpeername()。