这篇文章主要是用来对UDP重要知识复习用的,所以基础大家可以参考之前的内容:
1.UDP相比于TCP有哪些不同点?
UDP是面向无连接的、不可靠的、头部字节仅有8字节、支持向多个目标发送,支持多播,不存在流量控制和拥塞控制,发送的数据无法保证顺序,适用于注重实时性的应用
2.UDP协议格式?
UDP首部---8字节
16位源端口 16位目的端口
16位UDP长度 16位UDP检验和
数据部分
UDP首部+UDP数据 <= 64K
注意点:16位UDP长度是首部+数据总长度
3.UDP有哪些缺点,又该如何解决?
首先UDP是没有确认机制和重传机制的,无法保证数据正确传输到目的主机上,解决方法是在应用层来实现确认重传机制,例如在HTTP/3.0中利用UDP+QUIC协议实现,其次UDP协议无拥塞控制,解决方法还是在应用层实现一种限速方式来减少网络拥塞,最后UDP包最大是可以发送64K的,但是受限于MTU,UDP数据报最好每次发送的数据小于1472字节
4.手写UDP客户端和服务端(这个问题一般都不会考,大家大体知道就行)
server.cc
#include <iostream>
#include <sys/socket.h>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>
#define Port 8080
int main()
{
//创建UDP套接字
int server_fd = socket(AF_INET,SOCK_DGRAM,0);
//检查
if(server_fd < 0)
{
//失败
std::cerr<<"Socket creation failed"<<std::endl;
return -1;
}
//绑定地址和端口
struct sockaddr_in server_addr;//IPv4
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;//地址
server_addr.sin_port = htons(Port);
server_addr.sin_addr.s_addr = INADDR_ANY;//监听所有网卡
if(bind(server_fd,(sockaddr*)&server_addr,sizeof(server_addr))<0)
{
//绑定失败
std::cerr<<"Bind Failed"<<std::endl;
//注意:要关闭socket
close(server_fd);
return -2;
}
std::cout<<"UDP Server listening on Port"<<std::endl;
//接收和发送消息
char buffer[1024];//接收缓冲区
sockaddr_in cilent_addr;
socklen_t client_len = sizeof(client_addr);
while(true)//启动服务器,保证不退出
{
memset(buffer,0,sizeof(buffer));
int recv_len = recvfrom(server_fd,buffer,sizeof(buffer),0,(sockaddr*)&client_addr,&client_len);
//检查
if(recv_len < 0)
{
std::cerr<<"Recvfrom failed"<<std::endl;
break;
}
//将接受的信息进行操作,我们就只进行回复操作
const char* reply = "Server: message received!";
sendto(server_fd,reply,strlen(reply),(sockaddr*)&client_addr,client_len);
//注意client_len sendto和recvfrom写法是不同的
}
//关闭socket
close(server_fd);
return 0;
}
client.cpp
#include <iostream>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#define Port 8080
#define Server_IP "127.0.0.1"
int main()
{
//创建socket
int client_fd = socket(AF_INET,SOCK_DGRAM,0);
//检查
if(client_fd < 0)
{
std::cerr<<"Socket creation failed"<<std::endl;
return -1;
}
//配置服务器地址
sockaddr_in server_addr;
memset(%server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(Port);
inet_pton(AF_INET,Server_IP,&server_addr.sin_addr);
//发送和接受数据
char buffer[1024];
while(true)
{
std::cout<<"请输入数据:";
std::string message;
std::getline(std::cin,message);
if(message == nullptr)
break;
//发送数据到服务端
socklen_t server_len = sizeof(server_addr);
sendto(client_fd,message.c_str(),message.size(),0,(sockaddr*)&server_addr,server_len);
//接收服务端回复
memset(buffer,0,sizeof(buffer));
int recv_len = recvfrom(client_fd,buffer,sizeof(buffer),0,(sockaddr*)&server_addr,&server_len);
//检查
if(recv_len < 0)
{
std::cerr<<"Recvfrom failed"<<std::endl;
break;
}
//显示回复
std::cout<<"Server reply:"<<buffer<<std::endl;
}
//关闭Socket
close(client_fd);
return 0;
}
UDP大体上就是以上内容了,感谢你的支持!!!