我有以下程序(dgram sockets)从时间服务器检索时间。程序没有按预期打印出当前时间。
#define DAYTIME_SERVER_PORT 13
int main(int argc, char *argv[])
{
int connectionFd, in;
struct sockaddr_in servaddr;
char buf[BUFSIZ];
connectionFd = socket(AF_INET, SOCK_DGRAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(DAYTIME_SERVER_PORT);
inet_pton(AF_INET,"time.mit.edu", &servaddr.sin_addr);
sendto( connectionFd,buf ,1, 0,(struct sockaddr_in *)&servaddr, sizeof(servaddr) );
in = recv(connectionFd, buf, BUFSIZ, 0 ) ;
buf[in] = 0 ;
printf("Time is %s \n",buf);
close(connectionFd);
}
我的问题是-我在哪里犯错?任何代码更改和有价值的建议将不胜感激。我不知道如何使用recvform函数,因此尝试了recv。我连接的日间服务器
time.mit.edu
最佳答案
inet_pton()
不查找类似于time.mit.edu
的主机名。它只用于将ip地址的字符串形式(如"18.7.21.144"
)转换为套接字地址。
您应该使用getaddrinfo()
查找类似"time.mit.edu"
的名称。它还可以查找daytime
端口号。您的代码如下所示:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int main(int argc, char *argv[])
{
struct addrinfo *addr;
struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM };
int err;
int connectionFd, in;
char buf[1024];
err = getaddrinfo("time.mit.edu", "daytime", &hints, &addr);
if (err) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
return 1;
}
connectionFd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
sendto(connectionFd, "." , 1, 0, addr->ai_addr, addr->ai_addrlen );
freeaddrinfo(addr);
in = recv(connectionFd, buf, sizeof buf - 1, 0 ) ;
buf[in] = 0 ;
printf("Time is %s \n",buf);
close(connectionFd);
return 0;
}
(看,MA:支持IPv6的白天;)
当然,您还应该检查
socket()
、sendto()
和recv()
的返回值,就像我对getaddrinfo()
所做的那样。特别是,考虑如果recv()
失败并返回-1时会发生什么…关于c - 使用SOCK_DGRAM从服务器获取信息时出现问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4394412/