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

C 如果目标不存在,sendto()不会生成错误,c,udp,sendto,C,Udp,Sendto,我正在使用C中的sendto()函数。我已经设置了目标地址和目标端口。发送UDP帧时,我可以在Wireshark中看到帧,Wireshark显示的数据包数量与我在程序中定义的完全相同 问题是,即使无法访问目标地址,帧也会被发送,我可以在Wireshark中看到它 如果目标IP不存在,sendto()函数是否应该生成错误 if (sendto(sockfd, &buffer[i], UDP_FRAME, 0, (const struct socka

我正在使用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;
        }
if(发送到(sockfd,&buffer[i],UDP_帧,0,
(const struct sockaddr*)&server,sizeof(server))<0)
{
fprintf(stderr,“sendto()中的错误\n”);
//返回退出失败;
}
目的地。IP:234.168.0.1 目标端口:80或9(放弃协议)

#定义端口(80)
#定义帧(20000)
#定义UDP_帧(1442)
#定义服务器地址“234.168.0.1”
#定义缓冲区大小(帧*UDP\U帧)
字符缓冲区[缓冲区大小];
int main(int argc,字符**argv)
{
结构timespec开始、结束、循环开始、循环结束;
int sockfd,count_frame=0,frames_total,i=UDP_frame,n=1;
服务器中的结构sockaddr_;
printf(“构建数据…\n”);
构建(buffer,sizeof(buffer));
printf(“配置套接字…\n”);
sockfd=插座(AF_INET,SOCK_DGRAM,0);
if(sockfd<0)
{
fprintf(标准“错误打开插座”);
返回退出失败;
}
/*----------------------------------------------------*/
/*---初始化地址协议---*/
/*----------------------------------------------------*/
bzero((char*)&server,sizeof(server));
server.sinu family=AF\u INET;
server.sin\u addr.s\u addr=inet\u addr(服务器地址);
server.sin_port=htons(端口);
/*---------------------------------------------------*/
/*---S E N D I N D A T A--*/
/*---------------------------------------------------*/
printf(“\n发送UDP数据…\n\n”);
时钟获取时间(时钟单调、原始和开始);
时钟获取时间(时钟单调原始和循环开始);
总帧数=0;
对于(int i=0;i5000000){
printf(“\n计数[%d]…”,n);
printf(“发送的Fames:%d\n”,计数帧);
帧总数+=计数帧;
n+=1;
计数_帧=0;
时钟获取时间(时钟单调原始和循环开始);
}
}
printf(“成功计数的帧总数:%d\n”,帧总数);
返回退出成功;
}
sendto()
如果主机不知道到主机的路由,则会给您一个错误(这几乎是不可能的,因为您的主机将有一个默认网关)。否则,您可能会(也可能不会)如果数据包未到达目标应用程序,则接收ICMP destination unreachable消息,但这是不可靠的,并且不会通过调用
sendto()
进行通信

您可以做的是使用查询套接字

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

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

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


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

请尝试创建一个地址来显示给我们。另外,您是否100%确定该地址在Internet上的任何位置都不存在?@PaulOgilvie否,UDP数据报通信是(正常情况下)未连接,您需要显式指定目标主机,这只能通过
sendto
(这与
send
非常不同).@Someprogrammerdude我在问题中添加了代码,跳过了一些函数和行。看起来没问题。因此,问题可能只是UDP的常见问题:它不可靠。有很多情况可能会导致数据报在没有任何错误的情况下被丢弃。如果需要验证数据报是否到达,则需要创建一个在UDP之上的协议,例如序列编号和确认消息。然后使用超时,你可以重发或考虑数据包(和“连接”)丢失。@ Someprogrammerdude你的答案是有意义的。我想这会有所帮助。
struct sock_extended_err err;
socklen_t errlen = sizeof(err);
getsockopt(fd, SOL_IP, IP_RECVERR, &err, &errlen);