目录
一、UDP协议简介
UDP (User Datagram Protocol),用户数据报协议。UDP和TCP协议一起位于TCP/IP协议栈的传输层,在IP协议层之上。它是无连接的,而TCP协议是有连接的。报头结构如下图所示:
二、UDP SOCKET编程
2.1 UDP通信过程
2.2 UDP编程
三、asio UDP编程
3.1 io_context
io_context提供了I/O核心功能,所有使用asio模块的程序至少有1个io_context对象。
boost::asio::io_context io_context
3.2 boost::asio::buffer
在io操作中,对数据的读写大都是在一个缓冲区上进行的,在asio框架中,可以通过asio::buffer函数创建一个缓冲区来提供数据的读写。buffer函数本身并不申请内存,只是提供了一个对现有内存的封装,大小是自动管理的。
3.3 asio对IP的封装
boost::asio::udp
boost::asio::upd::socket,用于创建udp协议的套接字
它的常用方法有:
receive_from用于接收udp数据
send_to用于发送udp数据
创建udp套接字
boost::asio::udp::socket udpsock(io_context, endpoint(udp::v4(),port))
udp::v4()指定了sockaddr_in 的family 值为 AF_INET,v6()则指定了AF_INET6
endpoint:是对地址结构的封装。
然后就可以焦勇udpsock.receiver_from(boost::asio::buffer(data, max_length), sender_endpoint),
然后向sender_endpoint发送数据
udpsock.send_to(boost::asio::buffer(data, max_length), sender_endpoint)
3.4 全部代码
udpserver.cpp
#include <iostream>
#include <cstdlib>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
enum { max_length = 1024};
void server(boost::asio::io_context &io_context, unsigned short port){
udp::socket sock(io_context, udp::endpoint(udp::v4(), port));
for(;;){
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(boost::asio::buffer(data, max_length), sender_endpoint);
sock.send_to(boost::asio::buffer(data,length), sender_endpoint);
}
}
int main(int argc , char ** argv) {
try{
if(argc != 2){
std::cerr <<"Usage: server <port>
";
return 1;
}
boost::asio::io_context io_context;
server(io_context, std::atoi(argv[1]));
}
catch(std::exception &e){
std::cerr << "Exception:" << e.what() << "
";
}
return 0;
}
udpclient.cpp
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
enum { max_length = 1024};
int main(int argc, char** argv){
try {
boost::asio::io_context io_context;
udp::socket s(io_context, udp::endpoint(udp::v4(), 0));
udp::resolver resolver(io_context);
auto endpoints = resolver.resolve(udp::v4(), argv[1], argv[2]);
std::cout << "Enter message: ";
char request[max_length];
std::cin.getline(request, max_length);
size_t request_length = std::strlen(request);
s.send_to(boost::asio::buffer(request, request_length), *endpoints.begin());
char reply[max_length];
udp::endpoint epserver;
size_t reply_length = s.receive_from(boost::asio::buffer(reply, max_length), epserver);
std::cout << "Reply is";
std::cout.write(reply, reply_length);
std::cout << "
";
}
catch(std::exception &e){
std::cerr << "Exception" << e.what() << "
";
}
return 0;
}