UDP Server跟TCP Server不同,它是屬於connectionless的技術,因此不需要acceptor去跟client建立連線的步驟。我們只需要利用socket去bind特定的port後,就可以接收到資料。
一個Sync socket的流程如下,圖片引用自此:

在ASIO中的Server端程式碼:
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <string>
#include <boost/thread.hpp>
using namespace std;
void main(){
boost::system::error_code ec;
boost::shared_ptr<boost::asio::io_service> io_service(new boost::asio::io_service);
boost::shared_ptr<boost::asio::io_service::strand> strand(new boost::asio::io_service::strand(*io_service));
// boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work( *io_service ));
try{
boost::shared_ptr<boost::asio::ip::udp::socket> socket(new
boost::asio::ip::udp::socket(*io_service,
boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v6(), 12345)));
boost::asio::ip::udp::endpoint remote_endpoint;
while(true){
boost::array<char, 1> buf;
int size = socket->receive_from(boost::asio::buffer(buf), remote_endpoint, 0, ec);
if(ec){cout << "receive->" << ec.message() << endl;};
if(size != 0){
cout << "get access from->" << remote_endpoint.address() << endl;
}
std::string s;
s.append("->Server say hello to you!\n");
socket->send_to(boost::asio::buffer(s), remote_endpoint, 0, ec);
if(ec){cout << "send to->" << ec.message() << endl;};
}
}catch(std::exception e){
cout << e.what() << endl;
}
io_service->stop();
std::system("pause");
}
其中:boost::asio::buffer是一個function,它能夠將要傳輸的資料變成buffer object用來供socket將其分解成封包來進行資料的傳輸。
由於上面的程式是使用socket->receive_from,是屬於Sync socket的方法,因此這行會block住直到資料全部接收完畢才會往下執行。
同理socket->send_to也是屬於Sync socket的方法。
client端的程式碼:
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
udp::resolver resolver(io_service);
udp::resolver::query query(udp::v4(), "localhost", "12345");
udp::endpoint receiver_endpoint = *resolver.resolve(query);
udp::socket socket(io_service);
socket.open(udp::v4()); //udp是open後丟資料,不需要connect,然後等待接收(是誰送回來的再用sender_endpoint來確認)
boost::array<char, 1> send_buf;
socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);
boost::array<char, 100> recv_buf;
udp::endpoint sender_endpoint;
size_t len = socket.receive_from(
boost::asio::buffer(recv_buf), sender_endpoint);
std::cout.write(recv_buf.data(), len);
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
system("pause");
return 0;
}
boost::array<char, 100> recv_buf可以換成char recv_buf[100]。
Leave a Reply