ICMP“目的地不可达"udp 连接套接字上的数据包

编程入门 行业动态 更新时间:2024-10-27 04:36:21
本文介绍了ICMP“目的地不可达"udp 连接套接字上的数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我已经用这个函数创建了连接的 UDP 套接字

I've created connected UDP socket with this function

/* Creates connected udp socket */ int udp_connect( const char *host, const char *serv) { int sockfd, n; struct addrinfo hints, *res, *ressave; bzero(&hints, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; if ( ( n = getaddrinfo( host, serv, &hints, &res)) != 0) err_quit( "udp_connect error for %s, %s: %s", host, serv, gai_strerror(n)); ressave = res; do { sockfd = socket( res->ai_family, res->ai_socktype, res->ai_protocol); if ( sockfd < 0) continue; /* ignore this one */ /* The call to connect with a UDP socket does not send anything * to the peer. If something is wrong ( the peer is unreachable * or there is no server at the specified port), the caller * does not discover that until it sends * a datagram to the peer */ if ( connect( sockfd, res->ai_addr, res->ai_addrlen) == 0) break; /* success */ Close( sockfd); /* ignore this one */ } while ( ( res = res->ai_next) != NULL); if ( res == NULL) /* errno set from final connect() */ err_sys( "udp_connect error for %s, %s", host, serv); freeaddrinfo( ressave); return( sockfd); }

我想测试当对等点实际上无法访问时它的行为方式.由于对 connect() 的调用无法生成此信息,因此我们需要实际发送一些内容.我将在以下代码段中描述我要做什么以及我会得到什么:

I would like to do a test how it behaves when peer is actually unreachable. Since call to connect() cannot result in this information we need to actually send something. I will describe what do I do and what do I get in the following snippet:

printf( "sending to %s ", Sock_ntop_host( sa, salen)); // prints: sending to 127.0.0.1 Sendto( sockfd, "", 1, 0, sa, salen); /* send 1-byte datagram */ // prints: nbytes:1 // it is sent, I check via tcpdump or with Wireshark that datagram // has been sent and ICMP "destination unreachable" comes back from host printf( "sent, errno:%d,%s ", errno, strerror(errno)); // prints: sent, errno:0,Success n = Recvfrom( sockfd, recvline, MAXLINE, 0, NULL, NULL); // never gets here printf( "received n=%d ", n);

Sendto 函数是 sendto 的包装器,它只打印错误并退出:

The Sendto function is a wrapper over sendto that just prints error and exits:

void Sendto(int fd, const void *ptr, size_t nbytes, int flags, const struct sockaddr *sa, socklen_t salen) { if ( sendto(fd, ptr, nbytes, flags, sa, salen) == -1) exit(-1);//err_sys("sendto error"); printf( "nbytes:%d ",nbytes); // prints: nbytes:1 } ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags, struct sockaddr *sa, socklen_t *salenptr) { ssize_t n; if ( (n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0) err_sys("recvfrom error"); return(n); }

所以对 Recvfrom 的调用会永远阻塞,而 Sendto 会返回带有代码 Success 的 errno.我应该如何编写代码以获取有关 ICMP 响应的通知?这可能在套接字上没有超时吗?

So the call to Recvfrom blocks forever while Sendto returnes errno with code Success. How then should I code this to get notification about ICMP response? is this possible without timeout on socket?

推荐答案

一旦你connect()一个UDP socket,你就可以使用send()和recv() 而不是 sendto() 和 recvfrom().recv() 将报告已连接套接字的 ICMP 错误.

Once you connect() a UDP socket, you can use send() and recv() instead of sendto() and recvfrom(). recv() will report an ICMP error for a connected socket.

更多推荐

ICMP“目的地不可达"udp 连接套接字上的数据包

本文发布于:2023-11-15 16:31:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1596111.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:可达   数据包   目的地   ICMP   quot

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!