"Network Programming" basic UDP Socket programming

Source: Internet
Author: User
Tags socket error htons

The "UDP protocol" and "Socket data transfer" are described in the previous article. The UDP protocol differs from the TCP protocol in that it is a non-connected, unreliable transport layer protocol. In UDP socket-based programming, data transfer is available in functions SendTo and recvfrom. The following is the basic UDP socket programming Process:




SendTo and Recvfrom functions

The functions are similar to the write and read functions, and can be programmed with no connected sockets. It is defined as follows:

/* Function: send data; * Return value: If successful, returns the number of bytes sent, or 1 if an error occurs; * Function prototype: */#include <sys/socket.h>ssize_t sendto (int sockfd, void *buff, size_t nbytes, int flags, const struct SOCKADDR *destaddr, socklen_t addrlen);/* Description: * This function functions like the Write function except for         Identifier flags and destination address information, the same as other parameters; * Flags identifier value is as follows: * (1) Msg_dontroute do not route data out of local network * (2) msg_dontwait allow non-blocking operation * (3) Msg_eor If the agreement is supported, this is the end of the record * (4) Msg_oob If the protocol supports, sending out out-of-band data * If the sendto is successful, it simply means that the data is sent to the network without errors, and it is not guaranteed to reach the end correctly; * The function allows the connection to the socket without Send data between words (such as UDP sockets); */* Function: Receive data; * Return value: The length of the message in bytes, if no message is available or the other party has been ordered to end the return 0, if an error returns 1; * Function prototype: */#include <sys/socket.h& gt;ssize_t recvfrom (int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr *addr, socklen_t *add Rlen); /* Description: * This function function is similar to read; * If addr is not NULL, it will contain the socket address of the data sender; * * Flags identifier value is as follows: * (1) Msg_waitall wait for all data available * (2) Msg_dontwai T allow non-blocking operation * (3) Msg_peek View Read Data * (4) Msg_oob If protocol is supported, send out out of band data */

Programming based on UDP sockets

Below we use the UDP protocol to achieve a simple function, the client reads the data from the standard input and sends it to the server, the server receives the data and the data back to the client, and then the client receives the data from the server back to display it to the standard output. Its functionality is implemented as shown in:



Server programs


/* UDP Server */#include <string.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h># Include <sys/socket.h> #include <netinet/in.h> #define SERV_PORT 9877/* Universal port number */extern void Err_sys (const char *, ...);    extern void Dg_echo (int sockfd, struct sockaddr *addr, socklen_t addrlen); int main (int argc, char **argv) {int sockfd;    int err;    struct sockaddr_in servaddr, cliaddr;    /* Initialize server address information */bzero (&servaddr, sizeof (SERVADDR));    servaddr.sin_family = af_inet;    Servaddr.sin_port = htons (Serv_port);    SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);    /* Create a socket and bind the server address to the socket */if ((SOCKFD = socket (af_inet, SOCK_DGRAM, 0)) < 0) Err_sys ("Socket error");    Err =bind (SOCKFD, (struct sockaddr*) &servaddr, sizeof (SERVADDR));    if (Err < 0) Err_sys ("Bind error"); /* Server handler: reads the socket text line and shoots it back to the client */Dg_echo (SOCKFD, (struct sockaddr*) &cliaddr, sizeof (CLIADDR));}

Processing functions

#include "unp.h" Voiddg_echo (int sockfd, SA *pcliaddr, socklen_t clilen) {intn;socklen_tlen;charmesg[maxline];for (;;) {len = Clilen;n = Recvfrom (SOCKFD, MESG, MAXLINE, 0, pcliaddr, &len); Sendto (SOCKFD, MESG, N, 0, pcliaddr, len);}}

Client Programs

/* UDP client */#include <string.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h># Include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define SERV_PORT 9877/* Universal Port number * /extern void Err_sys (const char *, ...); extern void Err_quit (const char *, ...); extern void Dg_cli (FILE *fd, int sockfd, struct sockaddr *addr, socklen_t addrlen); int main (int argc, char **argv) {Intsock Fd;struct sockaddr_inservaddr;if (argc! = 2) err_quit ("Usage:udpcli <IPaddress>"); bzero (&servaddr, sizeof ( SERVADDR) servaddr.sin_family = Af_inet;servaddr.sin_port = Htons (Serv_port); Inet_pton (Af_inet, argv[1], & SERVADDR.SIN_ADDR); if ((SOCKFD = socket (af_inet, SOCK_DGRAM, 0)) < 0) Err_sys ("Socket err");/* Client handler function: reads text from standard input Line, send to the server, receive the back-shot text from the server and display it to the standard output */dg_cli (stdin, SOCKFD, (struct sockaddr *) &servaddr, sizeof (SERVADDR)); exit (0) ;}
Client-side processing functions

#include "Unp.h" voiddg_cli (FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) {Intn;charsendline[maxline], Recvline[maxline + 1];while (Fgets (Sendline, MAXLINE, fp)! = NULL) {/* sends a line of text read from the standard input to the server socket */sendto (SOCKFD, Sendline, St Rlen (Sendline), 0, pservaddr, servlen);/* Receives a line of text from the server's ejection */n = Recvfrom (SOCKFD, Recvline, MAXLINE, 0, NULL, NULL); recvline[ n] = 0;/* null terminate */fputs (Recvline, stdout);}}

$./serv &[1] 17911$./client 127.0.0.1sending text based on udpsending text based on Udpgoodbyte. Goodbyte.

Datagram Loss

Because UDP is an unreliable transport protocol. In the client/server program above, if the datagram is lost during transmission, the client is blocking the Recvfrom function call in the DG_CLI handler, waiting for a server answer that will never be reached. It is also possible that the client datagram successfully arrives at the server, but the server's response datagram is lost, and the client will always block the Recvfrom function call. In general, a time-out clock is set for the client recvfrom function call, but the timeout clock does not determine whether the client datagram cannot reach the server or the server answer cannot reach the client. So we can take the response that we received to verify. That is, the Recvfrom function is called to return the IP address and port number of the datagram sender, preserving the response from the datagram to the server.


Using the Connect function in UDP

When a UDP server is not started, the client does not echo the line of text after it has been typed. At this point the client is forever blocked from its recvfrom call, waiting for a server answer that never appears. Because the server does not start, it responds to a Port unreachable ICMP error message (that is, an asynchronous error), but the ICMP error message does not reach the client process, so the client process has no idea what is going on and is blocking its recvfrom call. To enable this asynchronous error to reach the client process, we can call the Connect function in UDP to make it a connected UDP socket, but the link does not cause three handshake processes like TCP. The kernel simply checks for an immediately known error, records the IP address and port number of the peer, and then immediately returns to the calling process.

The following is to differentiate between non-connected UDP sockets and connected UDP sockets:

    1. UDP Socket Not connected : The newly created UDP socket defaults to that condition;
    2. connected UDP sockets : The result of calling the Connect function on a UDP socket;

A connected UDP socket has the following changes to the non-connected UDP sockets:

    1. You cannot specify the destination IP address and port number for the output operation (as specified when the Connect function is called), that is, you cannot use the SendTo function, but instead use the Write or send function. The content written to the connected UDP socket will automatically be sent to the protocol address specified by connect;
    2. Instead of using the Recvfrom function to learn about the sender of the datagram, use the read, recv, or recvmsg functions instead. On a connected UDP socket, the datagram returned by the kernel for an input operation is only those datagrams from the protocol address specified by the Connect function. The destination is the local protocol address of the connected UDP socket, not the datagram of the Protocol address to which the socket was previously connect, and will not be delivered to the socket. That is, only the origin's protocol address matches the address specified by connect to transmit the datagram to the socket. This way the connected UDP sockets can only exchange datagrams with one peer;
    3. Asynchronous errors raised by a connected UDP socket are returned to the process they are in, and the UDP socket that is not connected does not receive any asynchronous errors;

A UDP client process or server process can call the Connect function only if it uses its own UDP socket to communicate with the identified unique peer. The call to connect function is typically a UDP client. The following is the client handler function that calls the Connect function:

#include "Unp.h" voiddg_cli (FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) {Intn;charsendline[maxline], Recvline[maxline + 1]; Connect (SOCKFD, (SA *) pservaddr, Servlen), while (Fgets (Sendline, MAXLINE, fp)! = NULL) {Write (SOCKFD, Sendline, strlen (SE Ndline)) n = Read (SOCKFD, Recvline, MAXLINE); Recvline[n] = 0;/* null terminate */fputs (Recvline, stdout);}}

At this point, the client receives an asynchronous error if the server is not started, only the client is started, and the text lines are typed.

$./client 127.0.0.1message...read Error:connection refused

Resources:

"Unix Network Programming"


Network programming basic UDP socket programming

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.