【发布时间】:2014-09-10 07:31:16
【问题描述】:
我正在尝试一个简单的客户端-服务器程序。在客户端,我绑定到特定地址。在服务器端,当我接受连接时,客户端地址被接收为 NULL。我在客户端和服务器端使用getaddrinfo 来获取服务器的IP 地址。
以下是客户端的sn-p代码:
s = getaddrinfo(argv[1], argv[2], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
int sockfd =0;
struct sockaddr_in localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_addr.s_addr = inet_addr("<local_ip_address>");
localaddr.sin_port = 0; // Any local port will do
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (bind(sfd, (struct sockaddr *)&localaddr, sizeof(localaddr)) !=0)
perror("failed to bind");
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
{
printf("connect success %d \n", rp->ai_family);
break; /* Success */
}
close(sfd);
}
以下是在服务器端:
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
hints.ai_flags = AI_PASSIVE ; /* For wildcard IP address */
hints.ai_protocol = IPPROTO_TCP; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
{
printf("bind success\n");
break; /* Success */
}
}
listen(sfd, 10);
struct sockaddr clientaddr;
socklen_t addrlen=0;
int port;
memset(&clientaddr, 0, sizeof(clientaddr));
int connfd = accept(sfd,
&clientaddr,
&addrlen);
s=getnameinfo((struct sockaddr *)&clientaddr, addrlen,
clienthost, sizeof(clienthost),
clientservice, sizeof(clientservice),
NI_NUMERICHOST);
if (s == 0)
printf("Received request from host=[%s] port=[%d]\n",
clienthost, clientservice);
else
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
当我执行程序时,我看到 getnameinfo 作为未知系列返回的错误。我使用 gdb 检查了clientaddr。将family显示为0。clientaddr中的所有数据为空。
【问题讨论】:
-
关于 ipv6 的说明(如果您想支持它)。 ipv6 地址大于
struct sockaddr。您可能希望使用addrlen = sizeof(struct sockaddr_in6); malloc(addrlen);来获取整个地址信息,即使它是 ipv6 地址。
标签: c sockets client-server getaddrinfo