C 时间程序 (NTP) 不绑定(bind)套接字

标签 c sockets ntp

我写了一个小程序,可以从 SNTP 服务器获取时间。遇到程序未绑定(bind)套接字的问题。我阅读了 RFC 2030,我正在按照它的解释做所有事情,使用 UDP,端口 123。还仔细检查了 UDP 不需要连接只需要绑定(bind)。我看不出我的错,调试器没有给我有用的信息。

这是我的代码:

#include <stdio.h>
#include <winsock2.h>
#include <winsock.h>
#include <Ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib" )
#define BUFFSIZE 1024

int main()
{
    WSADATA wsaData;
    int sockfd;
    char msg[48];
    unsigned long buffer[BUFFSIZE];
    int rv;
    int counter = 0;
    int numbytes;
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_storage their_addr;
    socklen_t addr_size;

    for(counter = 0; counter < 48; counter++)
        msg[counter] = 0;

    msg[0] = 11; //1 byte = 3 first flags set in binary: 00 001 011
    msg[1] = 0;
    msg[2] = 6;
    msg[3] = 1;
    msg[12] = 76;
    msg[13] = 79;
    msg[14] = 67;
    msg[15] = 76;


    if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0) 
    {
        fprintf(stderr, "WSAStartup failed.\n");
        exit(1);
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM; // Use UDP

    if ((rv = getaddrinfo("ntp.belnet.be", "123", &hints, &servinfo)) != 0) {
        fprintf(stderr, "Getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }
    // loop through all the results and make a socket
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {
            perror("Failed to create the socket\n");
            continue;
        }
        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            closesocket(sockfd);
            continue;
        }
        break;
    }
    if (p == NULL) {
        fprintf(stderr, "Failed to bind socket\n");
        return 2;
    }

    freeaddrinfo(servinfo);

    //zenden en vragen naar de tijd
    if ((numbytes = sendto(sockfd, msg, strlen(msg), 0,p->ai_addr, p->ai_addrlen)) == -1) {
        perror("Couldn't send the message.\n");
        exit(1);
    }

    addr_size = sizeof their_addr;
    if ((numbytes = recvfrom(sockfd, (char *)buffer, 12 * sizeof(buffer[0]) , 0,(struct sockaddr *)&their_addr, &addr_size))== -1) {
        perror("Failed Receive");
        exit(1);
    }

    closesocket(sockfd); //close the socket
    WSACleanup();
    return 0;
}

有人可以帮助我吗?我做错了什么?

编辑:已经发现这里的问题是解决方案:

if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0) 
{
    fprintf(stderr, "WSAStartup failed.\n");
    exit(1);
}

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; // Use UDP

if ((rv = getaddrinfo("ntp.belnet.be", "123", &hints, &servinfo)) != 0) {
    fprintf(stderr, "Getaddrinfo: %s\n", gai_strerror(rv));
    return 1;
}
// loop door al de resultaten en maak de socket
for(p = servinfo; p != NULL; p = p->ai_next) {
    if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {
        perror("Failed to create the socket\n");
        continue;
    }
    break;
}
//zenden en vragen naar de tijd
if ((numbytes = sendto(sockfd, msg, 48, 0,p->ai_addr, p->ai_addrlen)) == -1) {
    perror("Couldn't send the message.\n");
    exit(1);
}
addr_size = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, (char *)buffer, 48 , 0,(struct sockaddr *)&their_addr, &addr_size))== -1) {
    perror("Failed Receive");
    exit(1);
}

最佳答案

if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0) 
{
    fprintf(stderr, "WSAStartup failed.\n");
    exit(1);
}

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; // Use UDP

if ((rv = getaddrinfo("ntp.belnet.be", "123", &hints, &servinfo)) != 0) {
    fprintf(stderr, "Getaddrinfo: %s\n", gai_strerror(rv));
    return 1;
}
// loop door al de resultaten en maak de socket
for(p = servinfo; p != NULL; p = p->ai_next) {
    if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {
        perror("Failed to create the socket\n");
        continue;
    }
    break;
}
//zenden en vragen naar de tijd
if ((numbytes = sendto(sockfd, msg, 48, 0,p->ai_addr, p->ai_addrlen)) == -1) {
    perror("Couldn't send the message.\n");
    exit(1);
}
addr_size = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, (char *)buffer, 48 , 0,(struct sockaddr *)&their_addr, &addr_size))== -1) {
    perror("Failed Receive");
    exit(1);
}

关于C 时间程序 (NTP) 不绑定(bind)套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12844732/

相关文章:

node.js - socket.io/socket.io.js - 未找到。 Node.js、express.js 和 socket.io 应用程序

c - 如何在 ARM 中使用字符串?

C 从文本文件中解析注释

c++ - winsock:使用 localhost (127.0.0.1) 时连接失败并出现错误 10049

java - JVM 是否与操作系统保持时间同步?

embedded-linux - 只有在网络准备就绪后,在重新启动时运行 ntpdate 的最佳方法是什么

ntp - Cassandra 节点不同步 - NTP 不同步问题

c - int main() 和 void main() 是如何工作的?

c - 从字符串读取大小后分配大小为 'n' 的缓冲区

windows - AF_UNIX 等效于 Windows