में एएसओ सॉकेट ऑब्जेक्ट I C++ 11 सुविधाओं के साथ boost :: asio का उपयोग करके एक्सप्लोर कर रहा हूं। विशेष रूप से, मैं एक उदाहरण "async_tcp_echo_server.cpp" कहा जाता है पर ध्यान केंद्रित कर रहा हूँ, यहाँ (कोड भी मेरे सवाल के अंत में दिखाया गया है) स्थित:दोहराया गया std :: एक बूस्ट पर चाल :: सी ++ 11
मेरा प्रश्न server
की tcp::socket
सदस्य socket_
शामिल कक्षा। do_accept()
server
वर्ग की विधि, socket_
async_accept()
पर पास की गई है। (एएसओ दस्तावेज के अनुसार, async_accept()
को इसके पहले पैरामीटर के रूप में, socket
कनेक्शन को स्वीकार करने के लिए आवश्यक है।) अब तक, बहुत अच्छा है।
अगला पैरामीटर, एसिंक्रोनस स्वीकृति ऑपरेशन के लिए कॉलबैक, एक लैम्ब्डा फ़ंक्शन है। लैम्ब्डा का शरीर एक नया session
ऑब्जेक्ट बनाता है, जिसके निर्माता को भी socket
की आवश्यकता होती है। दिलचस्प बात यह है कि socket
वस्तुओं की प्रतिलिपि नहीं बनाई जा सकती है; इसलिए उदाहरण में, socket_
ऑब्जेक्ट, जो server
ऑब्जेक्ट का सदस्य है, std::move()
का उपयोग करके पारित किया गया है।
मैं समझता हूं कि "एक और केवल" socket_
ऑब्जेक्ट (जो server
ऑब्जेक्ट का "स्थायी" सदस्य है) session
ऑब्जेक्ट में "स्थानांतरित" हो गया है। ठीक - socket
ऑब्जेक्ट कॉपी नहीं किया गया है, लेकिन ले जाया गया - सबको खुश है।
लेकिन async_accept()
पर अगली कॉल पर क्या होता है? क्या वही socket_
(server
का सदस्य) है, जिसे पहले स्थानांतरित किया गया था, फिर से पारित किया गया था? जब हम एक सदस्य को "स्थानांतरित" करते हैं, तो पीछे क्या बचा है? क्या असीमित socket
ऑब्जेक्ट्स का जादुई फव्वारा है?
या यहां कुछ वास्तव में कम से कम स्पष्ट हो रहा है? जब socket
session
में ले जाया जाता, की सामग्री है (server
की socket_
सदस्य) वस्तु "पीछे छोड़ दिया/से चले गए" की सामग्री के साथ बदली 'नई' session
वस्तु के अपने "नहीं अभी तक का निर्माण" socket_
सदस्य? क्या मैं भी समझ में आता हूं?
सारांश
कोड नीचे है। कार्यक्रम प्रवाह काफी सरल है। main()
एक एकल server
ऑब्जेक्ट बनाता है। server
async_accept()
पर बार-बार कॉल करता है। प्रत्येक async_accept()
कॉलबैक एक नया session
ऑब्जेक्ट बनाता है, प्रत्येक एक (ताजा?) socket
के साथ बनाया गया है। सभी "ताजा" socket
ऑब्जेक्ट्स कहां से आते हैं, यदि वे (0) server
में उसी socket_
सदस्य से (बार-बार) "स्थानांतरित" होते हैं?
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
class session
: public std::enable_shared_from_this<session>
{
public:
session(tcp::socket socket)
: socket_(std::move(socket))
{}
void start() {
do_read();
}
private:
void do_read() {
auto self(shared_from_this());
socket_.async_read_some(
boost::asio::buffer(data_, max_length),
[this, self](boost::system::error_code ec, std::size_t length)
{
if(!ec) {
do_write(length);
}
}
);
}
void do_write(std::size_t length) {
auto self(shared_from_this());
boost::asio::async_write(
socket_,
boost::asio::buffer(data_, length),
[this, self](boost::system::error_code ec, std::size_t /*length*/)
{
if(!ec) {
do_read();
}
}
);
}
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
class server {
public:
server(boost::asio::io_service& io_service, short port)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
, socket_(io_service)
{
do_accept();
}
private:
void do_accept() {
acceptor_.async_accept(
socket_,
[this](boost::system::error_code ec)
{
if(!ec) {
std::make_shared<session>(std::move(socket_))->start(); // is this a *swap* of socket_ ???
}
do_accept();
}
);
}
tcp::acceptor acceptor_;
tcp::socket socket_;
};
int main(int argc, char* argv[]) {
try {
if(argc != 2) {
std::cerr << "Usage: async_tcp_echo_server <port>\n";
return 1;
}
boost::asio::io_service io_service;
server s(io_service, std::atoi(argv[1]));
io_service.run();
} catch(std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
प्रक्रिया का विवरण देने के लिए धन्यवाद! क्षमा करें मैंने आपके उत्तर को बहुत समय पहले नहीं देखा था। –