【UDP回声服务器】一篇文章搞懂UDP与TCP的区别,并且实现UDP的回声服务器

笔者上一篇的文章总结的TCP通信协议的特点与TCP回声服务器的代码实现,所以这一次,再对UDP通信协议进行一次总结

1、UDP回声服务器的概念

1.1 什么是UDP?

  UDP 的全称为用户数据报协议(UDP, User Datagram Protocol) 它是一个无连接的传输协议.UDP为应用程序提供了一种无需连接就可以发送封装的IP数据包的方法。

1.2 什么是回声服务器?

  回声服务器是指一种收到客户端发送的消息后,将消息回传至客户端服务器,这种服务器代码简单,但功能健全,非常适合帮助初学者理解网络编程中UDP通信协议。

2、UDP与TCP的区别

笔者在此总结一张表概括UDP与TCP的区别

UDP TCP
是否连接 无连接 面向连接
是否可靠 不可靠传输,不使用流量控制和拥塞控制 可靠传输,使用流量控制和拥塞控制
连接对象个数 支持一对一,一对多,多对一和多对多交互通信 只能是一对一
传输方式 面向报文 面向字节流
适用场景 适用于实时应用(IP电话、视频会议、直播等) 适用于要求可靠传输的应用,例如文件传输

3、UDP回声服务器的编程模型

3.1 编程模型

服务器端 S 客户端 C
创建套接字socket 创建套接字socket
准备通信地址(服务器的地址) 准备通信地址(服务器的地址)
绑定套接字和通信地址 连接服务器端S
接收/发送数据 发送/接收数据
关闭套接字 关闭套接字

3.2 服务器端编程步骤

  //创建套接字

  //准备通信地址

  //绑定socket与通信地址

  //接收数据,将接收到的数据存入缓冲区

  //发送数据,将缓冲区的数据发送出去

  //关闭套接字

3.3 客户端编程步骤

  //创建套接字

  //准备通信地址

  //发送数据

  //接收数据

  //关闭套接字

4、代码实现

4.1 服务器端代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

typedef struct sockaddr* SP;

int main(int argc,const char* argv[])
{
    
    
	// 创建socket对象 
	int svr_sock = socket(AF_INET,SOCK_DGRAM,0);
	if(0 > svr_sock)
	{
    
    
		perror("socket");
		return EXIT_FAILURE;
	}

	// 准备通信地址(自己的)
	struct sockaddr_in svr_addr = {
    
    } , cli_addr = {
    
    };
	svr_addr.sin_family = AF_INET;
	svr_addr.sin_port = htons(1324);
	svr_addr.sin_addr.s_addr = inet_addr("192.168.0.113");
	socklen_t addrlen = sizeof(svr_addr);

	// 绑定地址与socket对象
	if(bind(svr_sock,(SP)&svr_addr,addrlen))
	{
    
    
		perror("bind");
		return EXIT_FAILURE;
	}

	char buf[4096] = {
    
    };
	size_t buf_size = sizeof(buf);

	for(;;)
	{
    
    
		// 接收数据和来时的地址
		size_t ret_size = recvfrom(svr_sock,buf,buf_size,0,(SP)&cli_addr,&addrlen);	
		if(0 >= ret_size)
		{
    
    
			perror("recvfrom");
			// 关闭socket对象
			close(svr_sock);
			return EXIT_FAILURE;
		}
		printf("from:%s recv:[%s] bits:%d\n",inet_ntoa(cli_addr.sin_addr),buf,ret_size);
		sprintf(buf,"return:%s",inet_ntoa(svr_addr.sin_addr));
		// 返回数据
		sendto(svr_sock,buf,strlen(buf)+1,0,(SP)&cli_addr,addrlen);
	}
}

4.2 客户端代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

typedef struct sockaddr* SP;
int main(int argc,const char* argv[])
{
    
    
	// 创建socket对象
	int is_broadcast = 1;
	int cli_sock = socket(AF_INET,SOCK_DGRAM,0);
	if(0 > cli_sock)
	{
    
    
		perror("socket");
		return EXIT_FAILURE;
	}
	setsockopt(cli_sock,SOL_SOCKET,SO_BROADCAST,&is_broadcast,sizeof(is_broadcast));

	// 准备通信地址(服务端的)
	struct sockaddr_in svr_addr = {
    
    };
	svr_addr.sin_family = AF_INET;
	svr_addr.sin_port = htons(1324);
	svr_addr.sin_addr.s_addr = inet_addr("192.168.0.255");
	socklen_t addrlen = sizeof(svr_addr);

	char buf[4096] = {
    
    };
	size_t buf_size = sizeof(buf);

	for(;;)
	{
    
    
		printf(">>>");
		gets(buf);
		if(0 == strcmp("quit",buf))
		{
    
    
			printf("退出通信!\n");
			close(cli_sock);
			return EXIT_SUCCESS;
		}

		// 向服务器发送数据
		sendto(cli_sock,buf,strlen(buf)+1,0,(SP)&svr_addr,addrlen);
		// 从服务器接收数据
		size_t ret_size = recvfrom(cli_sock,buf,buf_size,0,(SP)&svr_addr,&addrlen);
		if(0 >= ret_size)
		{
    
    
			perror("recvfrom");
			// 关闭socket对象
			close(cli_sock);
			return EXIT_FAILURE;
		}
		printf("from:%s recv:[%s] bits:%d\n",inet_ntoa(svr_addr.sin_addr),buf,ret_size);
	}
}

5、结尾

  笔者在本文中总结了UDP通信协议与TCP通信协议的区别,同时用代码具体实现了基于UDP通信协议的回声服务器,通过阅读本文,相信一定能帮助读者更加形象的了解TCP/UDP两种通信协议。

猜你喜欢

转载自blog.csdn.net/weixin_48994377/article/details/108576602