2011-09-26 46 views
1

我写一个服务器 - 客户端程序,并在服务器中我使用getaddrinfo和getsockname在服务器上,以获取有关本地IP地址和本地绑定端口号的信息返回。 使用此信息,我启动我的客户端程序并使用getaddrinfo,然后仅打印出servinfo数据结构中的返回值: getaddrinfo(argc [1],argc [2],&提示,& servinfo); >>服务器主机名和服务器端口号通过命令行传递。sin_port中的getaddrinfo错误

但我注意到,在servinfo的sin_port是不是我通过命令行传递的端口。 1)这个getaddrinfo是否返回客户端使用的端口号作为源端口号? 2)getaddrinfo和套接字调用失败后,我的连接调用。我不知道为什么。我如何调试它?

我的客户代码片段:

memset(&hints, 0 ,sizeof hints); 
hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_flags = AI_CANONNAME | AI_NUMERICSERV; 
getaddrinfo(argc[1], argc[2], &hints, &servinfo); 

for (p = servinfo till p!=NULL) 
    sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol) 
    connect(sockfd, p->ai_addr, p->ai_addrlen) >>>>> Connect not going through. 

我开始了我的客户端程序是这样的: ./a.out myservername 18844个

谢谢!

+0

你怎么知道的getaddrinfo()没有失败,错误?你没有检查它的返回值是否为零。如果gettaddrinfo()失败,那么它当然不会写入数据到它的输出参数。 –

+0

我正在用servername调用它。但错过了将它添加到问题描述中。 – Vin

+0

我将检查getaddrinfo的返回码。它不应该失败,因为我能够读取以servinfo结构返回的IPv4地址。 – Vin

回答

4

新的答案:你只使用一个参数调用程序,所以argv[1]包含"18844"argv[2]是一个空指针。这将试图连接到一个数字IP 18844的主机和一个未指定的端口号(最终将为0并失败)。

老答案:(相关,但不是你的问题)sin_port和整个sockaddr_in结构是网络字节顺序。你需要的端口转换与ntohl使用它作为一个数字,但你会过得更好从来没有接触sockaddr结构内部任何责任。相反,使用getnameinfoNI_NUMERICHOSTNI_NUMERICSERV得到返回的地址到一个基于字符串的数字形式,然后strtol读端口(“服务”)数量为整数。即使对于非IPv4网络地址/协议族(如IPv6)也是如此,并且不需要额外的代码来支持新的代码。

+0

更不用说'argc'不是通常用于'argv'数组的名称。 –

+0

我会尝试。但是,sin_port是客户端端口吗?还是应该与我通过命令行传递的服务器端口相同?对不起,我很困惑。 – Vin

+0

您通过P-> ai_addr连接(),所以它会被用作地址,*连接到*,服务器的地址。如前所述,通过strace运行你的代码,你会看到connect()被调用的参数。 – nos

相关问题