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

我用这个函数创建了连接的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 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()不能产生这些信息,我们需要实际发送一些东西。 我将在下面的代码片段中描述我该怎么做以及我会得到什么:

 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); 

Sendto函数是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); } 

所以对Recvfrom的调用永远阻止,而Sendto返回errno代码Success那么我应该如何对此进行编码以获取有关ICMP响应的通知 ? 套接字没有超时可能吗?

connect() UDP套接字后,可以使用send()recv()而不是sendto()recvfrom()recv()将报告连接套接字的ICMP错误。