[英]ICMP “destination unreachable” packet on udp connected socket
I've created connected UDP socket with this function 我已经使用此功能创建了连接的UDP套接字
/* 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);
}
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. 由于对
connect()
调用无法产生此信息,因此我们实际上需要发送一些信息。 I will describe what do I do and what do I get in the following snippet: 在以下代码段中,我将描述我该做什么以及我将得到什么:
printf( "sending to %s\n", 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\n", errno, strerror(errno));
// prints: sent, errno:0,Success
n = Recvfrom( sockfd, recvline, MAXLINE, 0, NULL, NULL);
// never gets here
printf( "received n=%d\n", n);
The Sendto
function is a wrapper over sendto
that just prints error and exits: Sendto
函数是sendto
的包装,仅显示错误并退出:
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\n",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);
}
So the call to Recvfrom
blocks forever while Sendto
returnes errno with code Success
. 因此,在
Sendto
返回带有代码Success
errno时,对Recvfrom
的调用将永远Sendto
。 How then should I code this to get notification about ICMP response ? 那我该如何编码以获取有关ICMP响应的通知 ? is this possible without timeout on socket?
套接字没有超时可能吗?
Once you connect()
a UDP socket, you can use send()
and recv()
instead of sendto()
and recvfrom()
. 一旦
connect()
了UDP套接字,就可以使用send()
和recv()
代替sendto()
和recvfrom()
。 recv()
will report an ICMP error for a connected socket. recv()
将报告已连接套接字的ICMP错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.