UDP:

User datagram protocol

Features:

Connectionless protocol, unreliable, data leakage, fast transmission

USES:

(1) Send small-size data: for example, DNS server performs IP address query

(2) in the receiving data, give the response is difficult to use UDP network, such as: some wireless networks

(3) QQ, Feiqiu, MSN, and other instant messaging tools for audio and video data transmission and video conferencing and other related applications

(4) Streaming media, IPTV and other network multimedia services

(5) Broadcast and multicast communication

UDP server and client design ideas

Differences between UDP and TCP

(1) The second parameter of the socket

TCP: stream socket SOCK_STREAM

UDP: datagram socket SOCK_DGRAM

(2) UDP does not need listen,accept and connect

(3) Different data sent and received, such as UDP: recvfrom,sendto

Example Code 1

The server and client send messages to each other

/ / the server
#include <stdio.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

int main(int argc, char const *argv[])
{
	// create communication socket // domain datagram socket
	int s_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (s_socket == - 1)
	{
		perror("socket");
		return - 1;
	}
	// Socket set port reuse
	int reuse = - 1;
	if(setsockopt(s_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(reuse)) < 0)
	{
		perror("setsockopt error");
		return - 1;
	}

	//2. Initialize address structure
	struct sockaddr_in s_addr;
	memset(&s_addr, 0.sizeof(s_addr));

	s_addr.sin_family = AF_INET;   / / address family
	s_addr.sin_port = 55628;		/ / the port number
	/ / s_addr. Sin_addr. S_addr = inet_addr (" 192.168.1.235 ");
	s_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	//3. Bind the local IP address structure of the server to the socket
	if(bind(s_socket, (struct sockaddr *)&s_addr, sizeof(struct sockaddr)))
	{
		perror("bind");
		return - 1;
	}
	printf("Server address binding successful \n");

	//4
	char r_buf[512];
	char w_buf[512];	
	// Define a structure to store the client address
	struct sockaddr_in c_addr;
	int len = sizeof(c_addr);

	while(1)
	{
		memset(r_buf, 0.sizeof(r_buf));
		memset(w_buf, 0.sizeof(w_buf));
		memset(&c_addr, 0.sizeof(c_addr));
		recvfrom(s_socket, r_buf, sizeof(r_buf), 0, (struct sockaddr *)&c_addr, &len);
		printf("Buf: % s \ n", r_buf);
		printf("[%s][%d]\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));
		
		scanf("%[^\n]", w_buf);
		getchar();
		sendto(s_socket, w_buf, sizeof(w_buf), 0, (struct sockaddr *)&c_addr, sizeof(c_addr));

	}

	// close the socket
	close(s_socket);
	return 0;
}
Copy the code
/ / the client
#include <stdio.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

int main(int argc, char const *argv[])
{
	// create communication socket // domain datagram socket
	int c_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (c_socket == - 1)
	{
		perror("socket");
		return - 1;
	}
	// Socket set port reuse
	int reuse = - 1;
	if(setsockopt(c_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(reuse)) < 0)
	{
		perror("setsockopt error");
		return - 1;
	}

	//2. Initialize address structure
	struct sockaddr_in c_addr;
	memset(&c_addr, 0.sizeof(c_addr));

	c_addr.sin_family = AF_INET;   / / address family
	c_addr.sin_port = 55628;		/ / the port number
	c_addr.sin_addr.s_addr = inet_addr("192.168.1.11");

	//3, bind the local IP address structure of the server to the socket (optional)
	// if(bind(c_socket, (struct sockaddr *)&c_addr, sizeof(struct sockaddr)))
	/ / {
	// perror("bind");
	// return -1;
	// }
	// printf(" server address binding successful \n");

	//4
	char w_buf[512];
	char r_buf[512];

	// Define a server address structure to store IP addresses and port numbers
	struct sockaddr_in s_addr;
	int len = sizeof(s_addr);

	while(1)
	{
		memset(w_buf, 0.sizeof(w_buf));
		memset(r_buf, 0.sizeof(r_buf));
		scanf("%[^\n]", w_buf);
		getchar();
		sendto(c_socket, w_buf, sizeof(w_buf), 0, ( struct sockaddr *)&c_addr, sizeof(c_addr));	

		recvfrom(c_socket, r_buf, sizeof(r_buf), 0, (struct sockaddr *)&s_addr, &len);
		printf("Buf: % s \ n", r_buf);
		printf("[%s][%d]\n", inet_ntoa(s_addr.sin_addr), ntohs(s_addr.sin_port));
	}

	// close the socket
	close(c_socket);
	return 0;
}
Copy the code

The results

Example Code 2

Design a UDP server to achieve:

(1) Initialize the binding server IP, port number, and socket

(2) Circularly receiving messages

1. The client online message displays the IP address and port number of the current online client and records them

2. The chat information on the client is directly forwarded to the peer client

Design a UDP client program, to achieve:

(1) To send an online message when going online

(2) Thread 1: send messages (chat message mark, IP address of the other party, message content)

(3) Thread 2: receive messages and display

/ / the server
#include <stdio.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

// Create a list node structure to store address information
typedef struct node
{
	struct sockaddr_in client_addr;
	struct node *next;
}Node, *List;

// Message structure
struct MSG
{
	int flag; 			//1 indicates the online message, and 2 indicates the chat message
	char to_IP[20]; 	// Indicates the IP address to which the message is sent
	char from_IP[20];	// Indicates that the message is from that user IP
	char text[1024];	// Message content
};

int main(int argc, char const *argv[])
{
	// Initializes an empty list of leading nodes
	List caddr_list = malloc(sizeof(Node));
	// create communication socket // domain datagram socket
	int s_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (s_socket == - 1)
	{
		perror("socket");
		return - 1;
	}
	// Socket set port reuse
	int reuse = - 1;
	if(setsockopt(s_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(reuse)) < 0)
	{
		perror("setsockopt error");
		return - 1;
	}

	//2. Initialize address structure
	struct sockaddr_in s_addr;
	memset(&s_addr, 0.sizeof(s_addr));

	s_addr.sin_family = AF_INET;   / / address family
	s_addr.sin_port = 55558;		/ / the port number
	/ / s_addr. Sin_addr. S_addr = inet_addr (" 192.168.1.235 ");
	s_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	//3. Bind the local IP address structure of the server to the socket
	if(bind(s_socket, (struct sockaddr *)&s_addr, sizeof(struct sockaddr)))
	{
		perror("bind");
		return - 1;
	}
	printf("Server address binding successful \n");

	//4
	struct MSG rmsg;
	// Define a structure to store the client address
	struct sockaddr_in c_addr;
	int len = sizeof(c_addr);

	while(1)
	{
		bzero(&rmsg, sizeof(rmsg));
		recvfrom(s_socket, &rmsg, sizeof(rmsg), 0, (struct sockaddr *)&c_addr, &len);


		// Client online information
		if (rmsg.flag == 1)
		{
			// Print the user online
			printf("User [%s:%d] online \n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));
			// Add the user to the list
			List new = malloc(sizeof(Node));
			if (new= =NULL)
			{
				printf("Failed to create new node \n");
				continue;
			}
			new->client_addr = c_addr;
			new->next = NULL;
			// Insert this node into the linked list
			new->next = caddr_list->next;
			caddr_list->next = new;
			printf("New user info logged \n");
		}
		// Send a message
		else		
		if (rmsg.flag == 2)// Client chat information
		{
			List p = caddr_list;
			while(p->next ! =NULL)
			{
				p = p->next;
				if (strcmp(inet_ntoa(p->client_addr.sin_addr), rmsg.to_IP) == 0)
				{
					strcpy(rmsg.from_IP, inet_ntoa(c_addr.sin_addr));
					sendto(s_socket, &rmsg, sizeof(rmsg), 0, 
						(struct sockaddr *)&(p->client_addr), 
						sizeof(struct sockaddr_in)); }}}// else
		// if (rmsg.flag == 3)// Offline
		/ / {
		// // Find the source address of the message, remove it from the linked list, and print XXX offline
		// }
	}

	// close the socket
	close(s_socket);

	return 0;
}
Copy the code
/ / the client
#include <stdio.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

// Message structure
struct MSG
{
	int flag; 			//1 indicates the online message, and 2 indicates the chat message
	char to_IP[20]; 	// Indicates the IP address to which the message is sent
	char from_IP[20];	// Indicates that the message is from that user IP
	char text[1024];	// Message content
};

void *recv_msg(void *arg)
{
	int c_socket = *(int *)arg;
	// Define a server address structure to store IP addresses and port numbers
	struct sockaddr_in s_addr;
	int len = sizeof(s_addr);
	struct MSG rmsg;
	while(1)
	{
		memset(&s_addr, 0.sizeof(s_addr));
		memset(&rmsg, 0.sizeof(rmsg));
		recvfrom(c_socket, &rmsg, sizeof(rmsg), 0, (struct sockaddr *)&s_addr, &len);
		printf("-------------------------------------------\n");
		printf("Message from [%s] : %s\n", rmsg.from_IP, rmsg.text);
		printf("-------------------------------------------\n"); }}int main(int argc, char const *argv[])
{
	// create communication socket // domain datagram socket
	int c_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (c_socket == - 1)
	{
		perror("socket");
		return - 1;
	}
	// Socket set port reuse
	int reuse = - 1;
	if(setsockopt(c_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(reuse)) < 0)
	{
		perror("setsockopt error");
		return - 1;
	}

	//2. Initialize address structure
	struct sockaddr_in c_addr;
	memset(&c_addr, 0.sizeof(c_addr));

	c_addr.sin_family = AF_INET;   / / address family
	c_addr.sin_port = 55558;		/ / the port number
	c_addr.sin_addr.s_addr = inet_addr("192.168.1.235");

	// Send an online message first
	struct MSG one_msg = {1.""."".""};
	sendto(c_socket, &one_msg, sizeof(one_msg), 0, ( struct sockaddr *)&c_addr, sizeof(c_addr));

	//4
	struct MSG smsg;

	pthread_t pid;
	pthread_create(&pid, NULL, recv_msg, (void *)&c_socket);

	while(1)
	{
		memset(&smsg, 0.sizeof(smsg));
		smsg.flag = 2;
		scanf("%s%s", smsg.to_IP, smsg.text);
		getchar();
		sendto(c_socket, &smsg, sizeof(smsg), 0, ( struct sockaddr *)&c_addr, sizeof(c_addr));	
		printf("Send successful \n");	
	}

	// close the socket
	close(c_socket);
	return 0;
}
Copy the code