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