如果目标不存在,则sendto()不会生成错误

时间:2018-10-19 11:50:02

标签: c udp sendto

我在C中使用sendto()函数。我已经设置了目标地址和目标端口。发送UDP帧时,我可以在Wireshark中看到这些帧,Wireshark显示的数据包数量与我在程序中定义的完全一样。

问题是,即使无法到达目标地址,也正在发送帧,我可以在Wireshark中看到它。

如果目标IP不存在,sendto()函数是否会生成错误?

 if (sendto(sockfd, &buffer[i], UDP_FRAME, 0,
                    (const struct sockaddr*)&server, sizeof(server)) < 0)
        {
            fprintf(stderr, "Error in sendto()\n");
            //return EXIT_FAILURE;
        }

目的地。 IP:234.168.0.1 目标端口:80或9(丢弃协议)

    #define PORT (80)
    #define FRAMES (20000)
    #define UDP_FRAME (1442)
    #define SERVERADDRESS "234.168.0.1"
    #define BUFFER_SIZE (FRAMES * UDP_FRAME)
    char buffer[BUFFER_SIZE];

    int main(int argc, char **argv)
{
    struct timespec start, end, loop_start, loop_end;
    int sockfd, count_frame = 0, frames_total, i = UDP_FRAME, n=1;
    struct sockaddr_in server;

    printf("Build Data...\n");
    build(buffer, sizeof(buffer));

    printf("Configure socket...\n");
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        fprintf(stderr, "Error opening socket");
        return EXIT_FAILURE;
    }

    /*----------------------------------------------------*/
/*---       Initialize address protocol            ---*/
/*----------------------------------------------------*/

    bzero((char*)&server, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(SERVERADDRESS);
    server.sin_port = htons(PORT);

    /*---------------------------------------------------*/
/*---       S E N D I N G   D A T A        --*/
/*---------------------------------------------------*/

    printf("\nSend UDP data...\n\n");
    clock_gettime(CLOCK_MONOTONIC_RAW, &start);
    clock_gettime(CLOCK_MONOTONIC_RAW, &loop_start);
    frames_total = 0;

    for (int i = 0; i < BUFFER_SIZE; i += UDP_FRAME) {
    //while(1) {    

        if (sendto(sockfd, &buffer[i], UDP_FRAME, 0,
                    (const struct sockaddr*)&server, sizeof(server)) < 0)
        {
            fprintf(stderr, "Error in sendto()\n");
            //return EXIT_FAILURE;
        }
    count_frame += 1;

    clock_gettime(CLOCK_MONOTONIC_RAW, &loop_end);
    if ((loop_end.tv_nsec - loop_start.tv_nsec) > 5000000) {
        printf("\nCount [%d] ... ", n);
        printf("Fames sent: %d\n", count_frame);
        frames_total += count_frame;
        n+=1;
        count_frame = 0;
        clock_gettime(CLOCK_MONOTONIC_RAW, &loop_start);
    }

    }
    printf("Total successful counted frames: %d \n", frames_total);

    return EXIT_SUCCESS;
}

2 个答案:

答案 0 :(得分:0)

如果主机不知道到主机的路由,则

sendto()会给您一个错误(由于您的主机将具有默认网关,因此几乎永远不会这样)。否则,如果您的数据包没有到达目标应用程序,您可能会(也可能不会)收到ICMP目标不可达消息,但这是不可靠的,并且不会通过调用sendto()来传达。

您可以使用的查询套接字

struct sock_extended_err err;
socklen_t errlen = sizeof(err);
getsockopt(fd, SOL_IP, IP_RECVERR, &err, &errlen);

表示收到的错误,它将为您提供有关套接字上收到的错误的详细信息(即ICMP端口不可达,ICMP主机不可达等。pp)。这可以提供帮助,但正如我所说,这是不现实的,因为如果您的数据包被数据包过滤器(防火墙)阻止,则ICMP消息通常受到严格的速率限制,途中过滤或根本不发送。

答案 1 :(得分:0)

UDP是不可靠的协议。一旦数据包离开接口,对sendto的调用就会成功。之后,是否到达目的地取决于网络。

即使网络支持表明主机或端口不可访问的ICMP消息,在您的特定情况下也没有关系,因为您要发送到多播地址。如果您至少有一个支持多播的接口,系统将选择一个接口来发送数据包。它可以被多个(或没有)主机接收。因此,说目的地不可达是没有道理的。

相关问题