2010-11-15 105 views
5

我正在写a clone of inetd,其中我必须运行一个服务器来打印连接到它的客户端的IP和端口。从套接字描述符中恢复IP /端口

正如我覆盖STDINSTDOUT与socket描述符,my initial solution这样做是为了恢复sockaddr_in结构,其中包含了所需的信息。但是,使用getsockname()执行此操作时,将返回一个空结构,并将所有位设置为0.

任何有关我的方法出了什么问题的想法?有没有其他方法可以用来恢复IP /端口?

感谢

回答

8

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

此外,最后一个参数getsocknamegetpeername应该是一个指针socklen_t,而不是一个常数,你应该使用TCP/IP一个sockaddr_in

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

看到一个完整的例子here

+0

OP提到用套接字的文件描述符“覆盖”stdin和stdout,但这可能表明替换操作不正确,stdin(fd 0)实际上不是套接字... – 2010-11-15 16:10:58

+0

@R ..,在https://github.com/konr/Licio/blob/master/05/time查看他的代码。c – 2010-11-15 16:12:26

+1

不知道,如果这是* *问题,但使用'struct sockaddr',除非作为'void *'真正丑陋的替代品,这总是一个错误。你不应该有'struct sockaddr'类型的实际对象。根据需要始终使用'struct sockaddr_in','struct sockaddr_in6'或'struct sockadd_storage'。 – 2010-11-15 16:42:54

3

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

编辑:我想我发现你的实际bug读取代码。这条线是错误的:

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}); 

您也应该检查返回值;如果你这样做了,你会发现它正在返回错误。

+0

没有用,结果仍然是0. – konr 2010-11-15 15:59:06

+2

如果你的意思是getpeername()返回0,则表示函数已经成功。 – Simone 2010-11-15 16:00:43