从套接字描述符中恢复IP /端口

时间:2010-11-15 15:53:56

标签: c sockets tcp inetd

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

当我用套接字描述符覆盖STDINSTDOUT时,my initial solution执行此操作是为了恢复包含所需信息的sockaddr_in结构。但是,对getsockname()执行此操作会返回一个空结构,所有位都设置为0。

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

由于

3 个答案:

答案 0 :(得分:9)

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

此外,getsocknamegetpeername的最后一个参数应该是指向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));

getsocknamegetpeername函数将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()