使用SOCK_DGRAM从服务器获取信息时出现问题

Ete*_*ner 0 c sockets linux

我有以下程序(DGRAM套接字)来从时间服务器检索时间.该程序不会按预期打印出当前时间.

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


}
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 我在哪里弄错了?任何代码更改和宝贵的建议表示赞赏.我不知道如何使用recvform函数,因此尝试了recv.我连接的日间服务器是time.mit.edu

caf*_*caf 9

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;
}
Run Code Online (Sandbox Code Playgroud)

(看,马云:支持IPv6的白天;)

当然,你也应该检查返回值socket(),sendto()并且recv(),就像我做了getaddrinfo().特别是,考虑如果recv()失败并返回-1 会发生什么......