[Network] Socket programming - UDP

1. Getting to know UDP first

1. UDP protocol

  1. UDP is 无连接的, that is, there is no need to establish a connection before sending data (there is no connection to release at the end of sending data), which reduces overhead and delay before sending data
  2. UDP is used 尽最大努力交付, that is, reliable delivery is not guaranteed, and the host does not need to maintain a complicated connection state table (such as sending a text message, you cannot be sure whether the other party received it)
  3. UDP: Yes 面向报文, the sender's UDP will deliver the packet to the IP layer after adding the header to the packet handed over by the application. UDP neither merges nor splits the packets delivered by the application layer, but保留这些报文的边界
  4. UDP , network congestion will not reduce the sending rate of the source host. This is important for some real-time applications 没有拥塞控制
  5. UDP supports one-to-one, one-to-many, many-to-one and many-to-many interactive communication
  6. UDP 首部开销小, only 8 bytes, shorter than TCP's 20-byte header

2.UDP header

Source port: 1 when you need a reply from the other party, and all 0 when you don’t need it

Destination Port: This must be used when the endpoint delivers the packet

Length: The length of the UDP user datagram, the minimum value is 8 (only the header)

Checksum: Checks whether there is an error in the transmission of UDP user datagrams. throw it away

3. UDP communication process

 2. UDP communication - scoket programming

UDP network communication (similar to sending/receiving SMS):

analogy

effect

Function

function

have mobile phone

There is a network communication protocol UDP

Create socket file

socket()

Have a mobile phone card (number)

The communication protocol needs to have its own network information

Bind (specify) the network information of the local current process

bind()

Fill in the other party's mobile phone number and send a text message

Send data using protocol

Add the other party's information to the protocol to send data (ip port)

sendto()

receive sms

Receive data using protocol

Receive data based on parsed information

recvfrom()

closure

no longer communicate

close communication

close()

1. Create a socket

#include <sys/types.h>

#include <sys/socket.h>

//Create a socket file, add a corresponding network communication protocol (file) to the process, and the return value is the file descriptor of the creation number (socket descriptor represents a set of protocols---sockets)

int socket(int domain, int type, int protocol);

Parameter 1:

int domain:地址族,选用那种网络层协议地址
AF_INET------IPV4
AF_INET6------IPV6

Parameter 2:

int type:套接字类型

SOCK_STREAM--------TCP

SOCK_DGRAM---------UDP

SOCK_RAW:原始套接字(没有传输层协议)

Parameter 3:

int protocol:套接字协议

           0:套接字默认协议

return value:

int:整数---------文件描述符(套接字文件)
成功:返回套接字描述符 >= 0
失败:返回-1

2. Bind the socket

#include <sys/types.h> /* See NOTES */

#include <sys/socket.h>

//Bind the local network information to the socket

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

Parameter 1:

int sockfd:绑定本地网络信息到哪个套接字上(绑定到哪一套协议上)

Parameter 2:

const struct sockaddr *addr:结构体地址,这个结构体中存储的本地网络信息(要绑定的网络信息ip、port)

struct sockaddr {//通用结构体,表示一个网络信息内容

    sa_family_t sa_family;

    char sa_data[14];

}

//IPV4 网络信息结构体

struct sockaddr_in {

    sa_family_t sin_family;//地址族 AF_INET

    in_port_t sin_port;//端口

    struct in_addr sin_addr;//结构体变量--ip地址

};



/* Internet address. */

struct in_addr {

  uint32_t s_addr;//ipv4地址

};

Parameter 3:

socklen_t addrlen:整数,结构体大小(确定信息结构体的大小)

return value:

成功:返回0

失败:返回-1

3. Send data

#include <sys/types.h>

#include <sys/socket.h>

//Use UDP protocol to send data

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

Parameter 1:

int sockfd:套接字对象,使用哪个套接字发送数据

Parameter 2:

const void *buf:要发送的数据的内存首地址

Parameter 3:

size_t len:发送的数据的大小

Parameter 4:

int flags:标志

0:阻塞发送

Parameter 5:

const struct sockaddr *dest_addr:发送的目标网络信息

Parameter 6:

socklen_t addrlen:结构体大小

return value:

成功:返回发送的字节数

失败:返回-1

4. Receive data

#include <sys/types.h>

 #include <sys/socket.h>

//Use UDP protocol to receive data

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

Parameter 1:

int sockfd:套接字,指定使用哪个套接字来接收(ip,port来进行检测)

Parameter 2:

void *buf:接收的数据的存放的地址

Parameter 3:

size_t len:指定能够接收存储的最大大小

Parameter 4:

int flags:标志

0:阻塞接收

Parameter 5:

struct sockaddr *src_addr:在接收数据时,存储发送方的ip和port,如果不需要写NULL

Parameter 6:

socklen_t *addrlen:存储信息结构体的大小,不需要写NULL

return value:

成功:返回收到的大小
失败:返回-1

5. Close the socket

int close(int fd)

3. Implementation code:

//通过UDP协议,发送数据,接收数据
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{

	//1、创建套接字,选择对应的网络通信协议组
	int socketfd = socket(AF_INET,SOCK_DGRAM,0);//当前进程使用UDP IP 协议
	/*	if(socketfd < 0)
		{
		return -1;
		}
		*/

	//2、绑定套接字,对套接字添加自己当前进行需要到本地网络信息

	struct sockaddr_in addr;//有一个IPV4网络信息结构体
	addr.sin_family  = AF_INET;//地址族-----IPV4
	addr.sin_port = htons(10000);//为当前进程添加的端口号为10000-------主机10000端字节序转换为网络字节序
	addr.sin_addr.s_addr = inet_addr("192.168.124.63");

	bind(socketfd,(struct sockaddr *)&addr,sizeof(addr));

	char buf[20];
	memset(buf,0,20);//清空buf
	struct sockaddr_in dest_addr;//接收方网络信息结构体
	dest_addr.sin_family  = AF_INET;//地址族-----IPV4
	dest_addr.sin_port = htons(2000);
	dest_addr.sin_addr.s_addr = inet_addr("192.168.124.27");

	while(1)
	{	
		fgets(buf,20,stdin);
		sendto(socketfd,buf,20,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));//发送

		memset(buf,0,20);//清空buf
		int num=recvfrom(socketfd,buf,20,0,NULL,NULL);
		printf("recv size is %d\n",num);
		printf("data is %s\n",buf);

	}
	return 0;
}

The communication result is shown in the figure below:

 

Guess you like

Origin blog.csdn.net/qq_53676406/article/details/129368533