Linux Network Programming basics 2-UDP

Source: Internet
Author: User

 

In one of the basics of Linux network programming, we talk about the connection and difference between the stream socket and the datagram socket. Let's briefly talk about UDP-based network programming.
Two common functions
Int recvfrom (int sockfd, void * buf, int len, unsigned int flags, struct sockaddr * from int * fromlen)
Int sendto (int sockfd, const void * msg, int len, unsigned int flags, struct sockaddr * to int tolen)
The meaning of sockfd, buf, And len is the same as that of read and write, indicating the socket descriptor, the buffer size sent or received, and respectively.
Recvfrom
Responsible
Sockfd receives data. If from is not NULL, the information source is stored in from. If you are not interested in the information source, you can set from and fromlen
Set to NULL. sendto is responsible for sending information to. In this case, the detailed information of the recipient is stored in.

The following is a simple example (from Understanding Unix/Linux Programming ):

Server Side (to receive the datagram, dgrecv. c uses the port number passed through the command line to establish a socket, and then enters the loop to receive and print the datagram sent from the client ):
/*************************************** *********************************
* Dgrecv. c-datativesreceiver
* Usage: dgrecv portnum
* Action: listens at the specfied port and reports messages
*/

# Include <stdio. h>
# Include <stdlib. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <netinet/in. h>

# Define oops (m, x) {perror (m); exit (x );}
/* The auxiliary functions make_dgram_server and get_internet_address will be defined in the file dgram. c provided later */
Int make_dgram_server_socket (int );
Int get_internet_address (char *, int, int *, struct sockaddr_in *);
Void say_who_called (struct sockaddr_in *);

Int main (int ac, char * av [])
{
Int port;/* use this port */
Int sock;/* for this socket */
Char buf [BUFSIZ];/* to receive data here */
Size_t msglen;/* store its length here */
Struct sockaddr_in saddr;/* put sender's address here */
Socklen_t saddrlen;/* and its length here */
 
If (ac = 1 | (port = atoi (av [1]) <= 0 ){
Fprintf (stderr, "usage: dgrecv portnumber \ n ");
Exit (1 );
}

/* Get a socket and assign it a port number */

If (sock = make_dgram_server_socket (port) =-1)
Oops ("cannot make socket", 2 );

/* Receive messaages on that socket */

Saddrlen = sizeof (saddr );
While (msglen = recvfrom (sock, buf, BUFSIZ, 0,
(Struct sockaddr *) & saddr, & saddrlen)> 0 ){
Buf [msglen] = '\ 0 ';
Printf ("dgrecv: got a message: % s \ n", buf );
Say_who_called (& saddr );
}
Return 0;
}
Void say_who_called (struct sockaddr_in * addrp)
{
Char host [BUFSIZ];
Int port;

Get_internet_address (host, BUFSIZ, & port, addrp );
Printf ("from: % s: % d \ n", host, port );
}
Client (create a socket and then use it to send messages to a specific host and port number passed in with command line parameters ):
/*************************************** ******************************
* Dgsend. c-datemedisender
* Usage: dgsend hostname portnum "message"
* Action: sends message to hostname: portnum
*/

# Include <stdio. h>
# Include <stdlib. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <netinet/in. h>

# Define oops (m, x) {perror (m); exit (x );}

Int make_dgram_client_socket ();
Int make_internet_address (char *, int, struct sockaddr_in *);

Int main (int ac, char * av [])
{
Int sock;/* use this socket to send */
Char * msg;/* send this mescript */
Struct sockaddr_in saddr;/* put sender's address here */

If (ac! = 4 ){
Fprintf (stderr, "usage: dgsend host port 'message' \ n ");
Exit (1 );
}
Msg = av [3];

/* Get a datemedisocket */

If (sock = make_dgram_client_socket () =-1)
Oops ("cannot make socket", 2 );

/* Combine hostname and portnumber of destination into an address */

If (make_internet_address (av [1], atoi (av [2]), & saddr) =-1)
Oops ("make addr", 4 );

/* Send a string through the socket to that address */

If (sendto (sock, msg, strlen (msg), 0,
(Struct sockaddr *) & saddr, sizeof (saddr) =-1)
Oops ("sendto failed", 3 );
Return 0;
}

Auxiliary Functions
/*************************************** ************************
* Dgram. c
* Support functions for datemedibased programs
*/

# Include <stdio. h>
# Include <unistd. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <arpa/inet. h>
# Include <netdb. h>
# Include <string. h>

# Define host Len 256

Int make_internet_address ();

Int make_dgram_server_socket (int portnum)
{
Struct sockaddr_in saddr;/* build our address here */
Char hostname [HOSTLEN];/* address */
Int sock_id;/* the socket */

Sock_id = socket (PF_INET, SOCK_DGRAM, 0);/* get a socket */
If (sock_id =-1) return-1;

/** Build address and bind it to socket **/

Gethostname (hostname, HOSTLEN);/* where am I? */
Make_internet_address (hostname, portnum, & saddr );

If (bind (sock_id, (struct sockaddr *) & saddr, sizeof (saddr ))! = 0)
Return-1;

Return sock_id;
}
Int make_dgram_client_socket ()
{
Return socket (PF_INET, SOCK_DGRAM, 0 );
}

Int make_internet_address (char * hostname, int port, struct sockaddr_in * addrp)
/*
* Constructor for an Internet socket address, uses hostname and port
* (Host, port)-> * addrp
*/
{
Struct hostent * hp;

Bzero (void *) addrp, sizeof (struct sockaddr_in ));
Hp = gethostbyname (hostname );
If (hp = NULL) return-1;
Bcopy (void *) hp-> h_addr, (void *) & addrp-> sin_addr, hp-> h_length );
Addrp-> sin_port = htons (port );
Addrp-> sin_family = AF_INET;
Return 0;
}

Int get_internet_address (char * host, int len, int * portp, struct sockaddr_in * addrp)
/*
* Extracts host and port from an internet socket address
** Addrp-> (host, port)
*/
{
Strncpy (host, inet_ntoa (addrp-> sin_addr), len );
* Portp = ntohs (addrp-> sin_port );
Return 0;
}

Makefile is as follows:
All: dgrecv.exe dgsend.exe
Dgrecv.exe:
Gcc dgrecv. c dgram. c-o dgrecv.exe
Dgsend.exe:
Gcc dgsend. c dgram. c-o dgsend.exe
Running result:
$./Dgrecv.exe 8901 &
$./Dgsend.exe ComputerName 8901 "Yeah, I am on fire"
Dgrecv: got a message: Yeah, I am on fire
From: 192.168.5.1: 1018

Summary:
Server: socket-> (fill Structure)-> bind-> recvfrom
Client: socket-> (fill Structure)-> sendto

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.