我正在编写服务器客户端程序,在服务器中,我在服务器上使用getaddrinfo和getsockname来获取有关本地IP地址和本地绑定端口号的信息。 使用此信息,我启动我的客户端程序并使用getaddrinfo,然后只打印出servinfo数据结构中返回的值: getaddrinfo(argc [1],argc [2],& hints,& servinfo); >>服务器主机名和服务器端口号通过命令行传递。
但是我注意到servinfo中的sin_port不是我通过命令行传递的端口。 1)此getaddrinfo是否将客户端使用的端口号作为源端口号返回? 2)getaddrinfo和socket调用失败后我的connect调用。我不知道为什么。我该如何调试呢?
我的客户端代码段:
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 :(得分:4)
新答案:您只使用一个参数调用程序,因此argv[1]
包含"18844"
,argv[2]
是空指针。这将尝试连接到具有数字IP 18844和未指定端口号的主机(最终将为0并且失败)。
旧回答:(相关但不是您的问题)sin_port
且整个sockaddr_in
结构位于网络字节顺序中。您需要使用ntohl
转换端口以将其用作数字,但最好永远不要触及sockaddr
结构'内部结构。相反,将getnameinfo
与NI_NUMERICHOST
和NI_NUMERICSERV
一起使用,将地址恢复为基于字符串的数字形式,然后strtol
将端口(“服务”)编号读入整数。这甚至适用于非IPv4网络地址/协议系列(如IPv6),并且不需要额外的代码来支持新的。