Linux programming UDP socket full guide

Source: Internet
Author: User
Tags snmp htons

This article will summarize the important knowledge points of UDP socket programming in Linux, whether it is developer haulage, or some remote knowledge points of UDP sockets, this paper will talk about. As far as possible, after reading an article, we have a more comprehensive understanding of the UDP socket. This article is divided into two topics, the first is a common UPD socket framework, the second is some of the UDP sockets are not commonly used but rather important knowledge points.

First, basic UDP socket programming

1. UDP Programming Framework
To use the UDP protocol for program development, we must first understand what is UDP? Here is a brief summary.

The Chinese of UDP (User Datagram Protocol) is called the User Datagram Protocol, which belongs to the transport layer. UDP is a non-connection-oriented protocol that does not establish a connection with the other, but rather sends the data I want to send directly to the other party. Therefore, UDP is suitable for applications where the amount of data transmitted at one time is low, the reliability requirement is not high, and the real-time requirement is high. Because UDP does not need to establish a class such as three handshake connection, and makes communication efficiency is very high.

UDP is widely used, such as some well-known application layer protocol (SNMP, DNS) are based on UDP, think, if SNMP is using TCP, each query request has to carry out three handshake, the time spent is estimated by the user can not tolerate, because this will produce noticeable lag. So UDP is a good choice of SNMP, if the query process has dropped packets is not OK, we start a query on the good, because the situation is not a lot of drops, it is better than every time the query is a bit easier to accept it.

UDP communication process is relatively simple, so it is relatively simple to build such a common UDP communication framework. The following is a framework diagram of UDP.





As can be seen from the above block diagram, the client needs only two steps (socket and sendto) to initiate a request, and the server side only needs three steps to receive the message from the client (socket, bind, recvfrom).

2. UDP Programming Common functions

#include <sys/types.h>          #include <sys/socket.h>int sockets (int domain, int type, int protocol);
Parameter domain: Used to set network traffic, the socket selects the family of the information protocol according to this parameter name                                     purpose          & Nbsp;              af_unix, af_ LOCAL          Local communication               af_inet                      -& nbsp   ipv4 internet protocols          //for Ipv4af_ INET6                       Ipv6 internet protocol s          //for ipv6af_ipx                             IPX&NBSP;- novell protocolsaf_netlink                     KERNEL&NBSP ; user interface device     af_x25                            ITU-T X.25 / ISO-8208 protocol    af_ax25                         AX.25&NBSP;PROTOCOLAF_ATMPVC                     &NBSP;ACCESS&NBSP;TO&N Bsp;raw atm pvcsaf_appletalk                 appletalk  & nbsp;                      af_packet                      low le Vel packet interface    &nbSp;  af_alg                         Interface  to kernel crypto api we only need to memorize af_inet and AF_INET6 for this parameter episode: Pf_xxx and Af_xxxWe look at the Linux network programming related code will find pf_xxx and af_xxx will be mixed, what difference do they have? The following is part of the UNP. The af_ prefix represents the address family (addr Family), and the pf_ prefix represents the protocol family (Protocol Family). Historically, there has been an idea that a single protocol family can support multiple address families, pf_ values can be used to create sockets, and af_ values are used for the address structure of sockets. In practice, however, a protocol family that supports multiple address families has never been implemented, and the PF_ value defined for a given protocol in header file <sys/socket.h> is always the same as the Af_ value of this protocol. So I still prefer to use af_xxx when I am actually programming.   Parameter type (list only the three most important): Sock_stream provides sequenced, reliable, two-way, connection-based byte streams. For Tcpsock_dgram Supports datagrams (connectionless, unreliable messages).  For Udpsock_raw provides RAW network protocol access. Raw type for providing raw network access Parameters protocol: set 0 to return a value: success: Non-negative file descriptor failed: 1
#include <sys/types.h> #include <sys/socket.h>ssize_t sendto (int sockfd, const void *buf, size_t len, int flag s,              const struct SOCKADDR *dest_addr, socklen_t Addrlen);
The first parameter SOCKFD: The socket interface file descriptor that is listening on the port, the second parameter is obtained through the socket BUF: The send buffer, which is often a consumer-defined array that contains the data to be sent the third parameter len: the size of the send buffer, in bytes, the fourth parameter, flags: Fill in 0. The fifth parameter dest_addr: a struct that points to the host address information of the receiving data, that is, the parameter specifies which host the data is to be sent to which process sixth parameter Addrlen: represents the length of the content pointed to by the fifth parameter return value: Success: Failed to return data length of successful send:-1

#include <sys/types.h> #include <sys/socket.h>ssize_t recvfrom (int sockfd, void *buf, size_t len, int flags,< C1/>struct sockaddr *src_addr, socklen_t *addrlen);
The first parameter SOCKFD: The socket interface file descriptor that is listening on the port, the second parameter is obtained through the socket BUF: The receive buffer, which is often a consumer-defined array that contains the received data the third parameter len: the size of the receive buffer, in bytes, the fourth parameter, flags: Fill in 0. The fifth parameter src_addr: The structure that points to the host address information of the sending data, that is, we can get from this parameter to the sixth parameter that the data is emitted by Addrlen: the length of the content pointed to by the fifth parameter: success: Failed to return the length of the received successful data: 1
#include <sys/types.h> #include <sys/socket.h>int bind (int sockfd, const struct sockaddr* my_addr, socklen_t Addrlen);
The first parameter is SOCKFD: The socket file descriptor for the listening port, the second parameter is obtained through the socket MY_ADDR: the size of the struct that needs to bind the IP and port third parameter addrlen:my_addr return value: Success: 0 Failure: 1
#include <unistd.h>int close (int fd);
The close function is relatively simple, just fill in the FD generated by the socket.

3. Building a UDP communication framework

Server

 1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h>     5 #include <string.h> 6 7 #define SERVER_PORT 8888 8 #define Buff_len 1024x768 9 void handle_udp_msg (int fd) 11 {12  Char Buf[buff_len];  Receive buffer, 1024 bytes socklen_t len;14 int count;15 struct sockaddr_in clent_addr;         CLENT_ADDR is used to record the address information of the sender (1), memset (buf, 0, buff_len); LEN = sizeof (CLENT_ADDR); 20  Count = Recvfrom (FD, buf, Buff_len, 0, (struct sockaddr*) &clent_addr, &len);             Recvfrom is a congestion function, and no data is always congested if (count = =-1) ("Recieve data fail!\n"); 24  return;25}26 printf ("client:%s\n", buf);  Print the information sent by the client memset (buf, 0, Buff_len); sprintf (buf, "I have recieved%d bytes data!\n", count);  Reply client29 printf ("server:%s\n", buf); Print the information you sent to SendTo (FD, buf, Buff_len, 0, (struct sockaddr*) &AMP;CLENT_ADDR, Len); Send the message to the client, notice the use of the CLENT_ADDR structure pointer}33}34/*37 server:38 socket-->bind-->recvfrom--& Gt;sendto-->close39 */40 int main (int argc, char* argv[]) (int. int SERVER_FD, ret;44 struct sockaddr_in ser) _ADDR; SERVER_FD = socket (af_inet, SOCK_DGRAM, 0); Af_inet:ipv4; sock_dgram:udp47 if (server_fd < 0) + ("Create socket fail!\n"), return-1;51}5  2 memset (&ser_addr, 0, sizeof (SER_ADDR)); ser_addr.sin_family = af_inet;55 ser_addr.sin_addr.s_addr = Htonl (Inaddr_any);  IP address, the need for network sequence conversion, Inaddr_any: Local address Ser_addr.sin_port = htons (Server_port);     Port number, requires the network sequence conversion of the SERVER_FD ret = bind (struct sockaddr*) &ser_addr, sizeof (SER_ADDR)); if (Ret < 0) 60   {fail!\n ("socket Bind"), return-1;63}64 handle_udp_msg (SERVER_FD); Processing received data (SERVER_FD); 0;69}

Client
 1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <string.h> 6 7 #define SERVER_PORT 8888 8 #define Buff_len 9 #define SERVER_IP "172.0.5.182" 10 11 1 2 void Udp_msg_sender (int fd, struct sockaddr* DST) (socklen_t len;16 struct sockaddr_in src;17 while ( 1) {n char buf[buff_len] = "TEST UDP msg!\n"; LEN = sizeof (*DST); printf ("client:%s\n",  BUF); Print the information you sent to SendTo (FD, buf, Buff_len, 0, DST, LEN), memset (buf, 0, Buff_len), Recvfrom (FD, b  UF, Buff_len, 0, (struct sockaddr*) &src, &len);  Receive information from the server in printf ("server:%s\n", buf); sleep (1); Send a message one second}28}29/*31 client:32 socket-->sendto-->revcfrom-->close33 */34 int main ( int argc, char* argv[]) $ {PNS int client_fd;38 struct sockaddr_in ser_addr;39-client_fd = socket (Af_inet, S Ock_dgraM, 0), if (CLIENT_FD < 0) ("Create Socket fail!\n"), return-1;45}46 47 memset (&ser_addr, 0, sizeof (SER_ADDR)), ser_addr.sin_family = af_inet;49//ser_addr.sin_addr.s_addr = inet_  Addr (server_ip); ser_addr.sin_addr.s_addr = htonl (Inaddr_any);  Note that the network sequence conversion is Ser_addr.sin_port = Htons (Server_port); Note the network sequence conversion of Udp_msg_sender (CLIENT_FD, (struct sockaddr*) &ser_addr); 0;58}
The above framework for a host of UDP communication on different ports, the phenomenon is as follows: We first set up the server side, waiting for service, and then we set up client side request service. Server side:

Client side: Their own host communication with their own is not very good, we want to communicate with other host how to do? Very simply, the comments on the 49th line of the client's code above are opened and commented out below, and in the macro definition, fill in the ServerIP that you want to communicate with. The phenomenon is as follows: Server side: Client side: So we realize the network communication between host 172.0.5.183 and 172.0.5.182. The UDP universal framework is built and we can use the framework to communicate with the specified host. If you want to learn the basics of UDP, the above knowledge is sufficient; If you want to continue to learn more about UDP socket Advanced knowledge (artifice), you can take some time to look down. second, advanced UDP socket programming

1. The Connect function of UDP
What the? UDP also has conenct? Is connect not intended for TCP programming?
Yes, there is a connect function in UDP network programming, but it is used only to indicate that the other party's address is determined and has no other meaning.
With this understanding, we can know that the UDP sockets have the following distinctions:
1) non-connected UDP sockets
2) connected UDP sockets

For non-connected sockets, which is our usual UDP sockets, we use Sendto/recvfrom to send and receive information, the IP and port of the target host is determined when the sendto/recvfrom is called;

Calling the SendTo function core on a non-connected UDP socket for two datagrams performs the following six steps:
1) Connecting sockets
2) output of the first datagram
3) Disconnect Socket connection
4) Connecting sockets
5) output a second datagram
6) Disconnect Socket connection

For a connected UDP socket, you must first go through connect to specify the target server, and then call Read/write to send and receive information, the IP and port of the destination host is determined at connect, that is, once the conenct is successful, We can only send and receive information to the host.

A connected UDP socket that calls the Write function core to two datagrams performs the following three steps:
1) Connecting sockets
2) output of the first datagram
3) output a second datagram

It is thus known that when the application process knows to send multiple datagrams to the port number of the same destination address, it is more efficient to display sockets.

A UDP communication framework with connect function is given below

The specific framework code is no longer given, because the code with no connect above, just a few more than a connect function processing, the following is the basic steps to deal with Conenct ().

void Udp_handler (int s, struct sockaddr* to) {    char buf[1024] = "TEST UDP!";    int n = 0;    Connect (s, to, sizeof (*to);     n = Write (s, buf, 1024x768);     Read (s, buf, n);}

2. UDP packet loss problem
Because of the characteristics of UDP itself, it is decided that UDP will have some difficult problems relative to TCP. The first one is the problem of UDP packet deletion.
In the case of the UDP server client, if the data sent by the client is lost, the server waits until the client's legitimate data comes up. If the server's response is routed in the middle, the client blocks until the server data comes up.

The general way to prevent such permanent blocking is to set a timeout for the client's recvfrom call, presumably in two ways:
1) Use signal SIGALRM to set timeout for recvfrom. First we establish a signal processing function for Sigalarm and set a timeout of 5 seconds through alarm before each call. If the recvfrom is interrupted by our signal processing function, it will be timed out and the alarm clock will be switched off if the data is read normally.

2) Set timeout for recvfrom using select
Set the fifth parameter of the Select function.

3. The problem of UDP message disorderly sequence
The so-called chaos is the order of sending data and the order of receiving data is inconsistent, for example, the order of sending data is a, B, C, but the order of the received data is: A, C, B. The reason for this problem is that each datagram route is not the same, some routes are smooth, some are congested, which causes each datagram to arrive at the destination in a different order. The UDP protocol does not guarantee the sequential receipt of datagrams.

The way to solve this problem is to send the data in the sending side of the serial number, so that the receiver receives the message can first check the sequence number of the datagram, and they queued up sequentially to form an orderly datagram.

4. UDP Traffic Control issues
It is well known that TCP has a sliding window for flow control and congestion control, and the anti-UDP is not possible because of its characteristics. When UDP receives data, it puts the data into the buffer directly, if the user does not copy the contents of the buffer in time, then the incoming data will go to the buffer, and when the buffer is full, Later data is overwritten with data loss (because the UDP buffer used by the kernel is a ring buffer). Therefore, once the sender sends a message at a point in time, the receiver will lose the information because it is too late to receive it.

The solution generally uses the increase of the UDP buffer, which makes the receiver more capable than the sender.

int n = 220 * 1024; 220kBsetsocketopt (SOCKFD, Sol_socket, So_rcvbuf, &n, sizeof (n));

This allows us to widen the receiver queue so as to avoid the loss of data. Bibliography:
"UNIX Network Programming Volume 1"
"Linux Network Programming"
Embedded Linux software development from beginner to proficient

Linux programming UDP socket full guide

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.