Socket Programming Practice (--UDP) Basics of programming

Source: Internet
Author: User
Tags socket error htons

UDP features

no connection , data transmission service for datagram (message-based, non-sticky);

Unreliable (May drop packets, disorderly order, repeat), but generally the UDP is more efficient;


UDP client/server model

udp-api use

#include <sys/types.h> #include <sys/socket.h>ssize_t recvfrom (int sockfd, void *buf, size_t len, int flags,< C3/>struct sockaddr *src_addr, socklen_t *addrlen); ssize_t sendto (int sockfd, const void *buf, size_t len, int flags,               const struct SOCKADDR *dest_addr, socklen_t Addrlen);

/** Practice: Implement a UDP-based echo Echo server/client**///server-end code void echoserver (int sockfd); int main () {int SOCKFD = socket (Af_inet,    SOCK_DGRAM, 0);    if (SOCKFD = =-1) err_exit ("Socket error");    struct sockaddr_in servaddr;    servaddr.sin_family = af_inet;    SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);    Servaddr.sin_port = htons (8001);    if (Bind (SOCKFD, (const struct sockaddr *) &servaddr, sizeof (servaddr)) = =-1) err_exit ("Bind error"); Echoserver (SOCKFD);}    void Echoserver (int sockfd) {char buf[bufsiz];    ssize_t recvbytes = 0;    struct sockaddr_in clientaddr;    Socklen_t Addrlen;        while (true) {memset (buf, 0, sizeof (BUF));        Addrlen = sizeof (CLIENTADDR);        memset (&clientaddr, 0, Addrlen); Recvbytes = Recvfrom (sockfd, buf, sizeof (BUF), 0, (struct sockaddr *) &clientaddr, &add        Rlen); If recvbytes=0, does not mean that the peer connection is closed because UDP is not connected if (Recvbytes < 0) {if (errno = = EINTR) continue;        else Err_exit ("Recvfrom error");        } cout << buf;            if (SendTo (SOCKFD, buf, Recvbytes, 0, (const struct sockaddr *) &clientaddr, addrlen) = =-1)    Err_exit ("SendTo error"); }}
/**client-Side code **/void echoclient (int sockfd); int main () {int SOCKFD = socket (af_inet, SOCK_DGRAM, 0);    if (SOCKFD = =-1) err_exit ("Socket error");    Echoclient (SOCKFD); cout << "Client exiting ..." << Endl;}    void echoclient (int sockfd) {struct sockaddr_in servaddr;    servaddr.sin_family = af_inet;    SERVADDR.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1");    Servaddr.sin_port = htons (8001);    Char Buf[bufsiz] = {0}; while (Fgets (buf, sizeof (BUF), stdin)! = NULL) {if (SendTo (SOCKFD, buf, strlen (BUF), 0, (cons        t struct sockaddr *) &servaddr, sizeof (servaddr)) = =-1) err_exit ("SendTo error");        memset (buf, 0, sizeof (BUF));        int recvbytes = Recvfrom (sockfd, buf, sizeof (BUF), 0, NULL, NULL);            if (recvbytes = =-1) {if (errno = = eintr) continue;        else Err_exit ("Recvfrom error");        } cout << buf; memset (buf, 0, sizeof (BUF));   }} 

Practice Analysis: Compile and run server, in two terminals each open a client and server interaction, you can see the server has the ability of concurrent services. Use <Ctrl+C> to close the server, and then run server, at which point the client can also contact the server. Compared with the result of the previous TCP program, we can realize the meaning of no connection. In the case of the UDP protocol, the boundary between server and client is more blurred, as long as the peer address (IP and port) is known to be able to proactively send data.

UDP Programming Considerations

1.UDP messages may be lost (retransmission over time), duplicated, scrambled (maintenance of a sequence number)

2.UDP Lack of flow control : When the buffer is full, the buffer is overwritten because UDP has no traffic control mechanism.

3. UDP packet Truncation : If the UDP datagram sent to the end is larger than the local receive buffer, the message may be truncated and the latter part will be lost (rather than being able to receive the next time as we imagined).

4.recvfrom can return 0, does not mean that the connection is closed, because UDP is not connected, on behalf of the sending side did not send any data [sendto can send data 0 packets (containing only UDP+IP header 40B)].

5.ICMP Async Error

Observe the phenomenon: using the example above, close the UDP server, start the client, accept the data from the keyboard, and then send the data. If the flags flag in Recvfrom is 0 and the client does not call connect, the UDP clients are blocked in the Recvfrom location (see test Code 3);

Description:

1) When UDP sends the paper, only copy the data to the send buffer. If the server is not up, it can be sent successfully .

2) The so-called ICMP asynchronous error refers to: When the message is sent, there is no error, when receiving the message recvfrom, the return to the ICMP reply.

3) Asynchronous error, unable to return an unbound socket, so if the above example we call connect, it is possible to receive the asynchronous ICMP packet;

6.UDP Call Connect

1)UDP call Connet, and no three handshake, just maintain a (and peer) state information , so we can see even if the server is not turned on, Connect on the client side can still be returned correctly! (Test code like test code 2)

2) One but call Connect, send can use Send/write, receive can use Recv/read function (see Test Code 3)

Determination of the 7.UDP outgoing interface:

Assuming that the client has multiple IP addresses, the parameters of the remote address provided by the CONNECT/SENDTO function, the system chooses an appropriate exit, such as the server's IP is 192.168.2.10, and the client's IP now has 192.168.1.32 and 192.168.2.75 will automatically choose 192.168.2.75 this IP to go out.

/** Test 1: Test note point 3, UDP packet truncation, recvfrom return-1, errno value is eagain**/int main () {int SOCKFD = socket (af_inet, SOCK_DGRAM, 0);    if (SOCKFD = =-1) err_exit ("Socket error");    struct sockaddr_in servaddr;    servaddr.sin_family = af_inet;    SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);    Servaddr.sin_port = htons (8001);    if (Bind (SOCKFD, (const struct sockaddr *) &servaddr, sizeof (servaddr)) = =-1) err_exit ("Bind error"); Send yourself data if (SendTo (SOCKFD, "ABCDE", 5, 0, (const struct sockaddr *) &servaddr, sizeof (servaddr)) = =    -1) err_exit ("SendTo error");        for (int i = 0; i < 5; ++i) {char ch;        int recvbytes = Recvfrom (SOCKFD, &ch, 1, msg_dontwait, NULL, NULL);            if (recvbytes = =-1) {if (errno = = eintr) continue;        else if (errno = = Eagain) err_exit ("Recvfrom error"); } else cout << "char =" << ch << ", recvbytes ="<< recvbytes << Endl; }}
/** Test 2:    The code of the client-side echoclient function is modified as follows, note that the program is executed when the server side is not open **/void echoclient (int sockfd) {struct sockaddr_in servaddr;    servaddr.sin_family = af_inet;    SERVADDR.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1");    Servaddr.sin_port = htons (8001); UDP Client Side calls Connect if (connect (sockfd, const struct sockaddr *) &servaddr, sizeof (servaddr)) = = 1) Err    _exit ("Connect error");    Char Buf[bufsiz] = {0}; while (Fgets (buf, sizeof (BUF), stdin)! = NULL) {if (SendTo (SOCKFD, buf, strlen (BUF), 0, (cons        t struct sockaddr *) &servaddr, sizeof (servaddr)) = =-1) err_exit ("SendTo error");        memset (buf, 0, sizeof (BUF));        int recvbytes = Recvfrom (sockfd, buf, sizeof (BUF), 0, NULL, NULL);        if (recvbytes = =-1) err_exit ("Recvfrom error");        cout << buf;    memset (buf, 0, sizeof (BUF)); }}
/** test the 3:client end calls send after calling Connect, instead of send**/void echoclient (int sockfd) {    struct sockaddr_in servaddr;    servaddr.sin_family = af_inet;    SERVADDR.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1");    Servaddr.sin_port = htons (8001);    UDP Client side calls connect    if (Connect (sockfd, const struct sockaddr *) &servaddr, sizeof (servaddr)) = = 1)        err _exit ("Connect error");    Char Buf[bufsiz] = {0};    while (Fgets (buf, sizeof (BUF), stdin)! = NULL)    {        if (send (SOCKFD, buf, strlen (BUF), 0) = =-1)            Err_exit ("Sen D error ");        memset (buf, 0, sizeof (BUF));        int recvbytes = recv (sockfd, buf, sizeof (BUF), 0);        if (recvbytes = =-1)            err_exit ("recv error");        cout << buf;        memset (buf, 0, sizeof (BUF));}    }


Socket Programming Practice (--UDP) Basics of programming

Related Article

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.