How does UDP return the connection refused error?

Source: Internet
Author: User
Sometimes, when writing a UDP socket program, when calling sendto or recvfrom, you will find that a connection refused error is returned, and the error code is econnrefused. For those who know the socket interface but do not know the network very well, this may not be a problem at all. Based on the error code, he will know that the remote end does not have this service port, as described in the socket API man manual:
Econnrefused
A remote host refused to allow the network connection (typically because it is not running the requested service ).
Sometimes ignorance is really a kind of happiness! However, if you are very familiar with the TCP/IP stack, you will not be able to figure it out. Since UDP is not connected, how can you know the remote connection? UDP does not work as it is described in the protocol standard? If Nowait is set, eagain is returned directly, indicating to try again later. In any case, no detailed information such as econnrefused will be returned.
Since UDP will not return any error information from the peer end, nothing else will be returned. This involves the data plane and control plane in the network protocol design. For messages in the control plane, it can be in-band transmission or out-of-band transmission. For TCP, it is undoubtedly in-band transmission, because it is a connected protocol, the protocol itself will handle any errors and exceptions, but for UDP, the purpose of its design is to maintain simplicity, so there is no built-in control message logic attached to it. The ICMP protocol is especially important on the Internet to make up for the lack of control logic for this type of protocol! In fact, ICMP is a special control protocol that controls and instructs the events at the IP layer.
Econnrefused is returned by ICMP! However, not all UDP sockets can receive error messages from ICMP. After all, the association between out-of-band control messages and the Protocol is too loose. UDP socket must be an explicit connect peer. Now the question comes again. Now that UDP is simply a connectionless protocol, what is the significance of connect? This is actually the scope of the socket interface design and has nothing to do with the Protocol itself. When a UDP socket goes to connect a remote end, it does not send any data packets, the effect is that a 5-tuple ing is established locally, corresponding to a peer. The ing is used to bind it with the ICMP control channel outside the UDP band, this makes the meaning of the UDP socket interface more full.
We know that when an ICMP error message is returned, the ICMP packet content is the original packet with the error. Based on this original packet, we can find a quintuple, the quintuple can correspond to a local connect UDP socket, and then the error message is transmitted to the socket. When the application calls the socket interface function, the error message is displayed. If a UDP socket does not call connect, even if an ICMP packet is returned, because the socket maintains the complete semantics of UDP, the protocol stack does not store any information about the socket and peer Association, so it cannot find a specific quintuple to send the error code to it.
The following is a test procedure:
#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <netinet/in.h>#include <stdio.h>#include <arpa/inet.h>#include <unistd.h>void test( int sd, struct sockaddr *addr, socklen_t len){        char buf[4];        connect(sd, (struct sockaddr *)addr, len);        sendto(sd, buf, 4, 0, (struct sockaddr *)addr, len);         perror("write");         sendto(sd, buf, 4, 0, (struct sockaddr *)addr, len);         perror("write");         recvfrom(sd, buf, 4, 0, (struct sockaddr *)addr, len);         perror("read");}int main(int argc, char **argv){        int sd;        struct sockaddr_in addr;        if(argc != 2) {                exit(1);        }        bzero(&addr, sizeof(addr));        addr.sin_family = AF_INET;        addr.sin_port = htons(12345);        inet_pton(AF_INET, argv[1], &addr.sin_addr);        sd = socket(AF_INET, SOCK_DGRAM, 0);        test(sd, (struct sockaddr *)&addr, sizeof(addr));        return 0;}

Compile it as udpclient and run./udpclient 192.168.1.20. Note that this address must be an IP address accessible for testing. According to the above theory, the result should be: the first sendto succeeds, and then 192.168.1.20 returns:
ICMP 192.168.1.20 UDP port 12345 unreachable, length 40
Next, the second sendto is returned:
Write: Connection refused
Because no packet is sent for the second time to reach 192.168.1.20, you cannot expect it to return an ICMP error message. Therefore, the subsequent recvfrom call will be blocked.
In the last question, you cannot expect this connection refused and all the error messages returned out of band, because you cannot guarantee that you will receive the ICMP packet sent from the remote end, if an intermediate node or local machine disables ICMP, these errors cannot be captured when the socket API is called.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.