Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何确保客户端首先使用boost asio关闭套接字_C++_Boost Asio - Fatal编程技术网

C++ 如何确保客户端首先使用boost asio关闭套接字

C++ 如何确保客户端首先使用boost asio关闭套接字,c++,boost-asio,C++,Boost Asio,服务器从客户端读取10个字节,然后写回10个字节,代码如下: 服务器: #include <iostream> using namespace std; #include <boost/thread/thread.hpp> #include <boost/asio.hpp> #include <boost/asio/spawn.hpp> using namespace boost; using namespace boost::asio; usi

服务器从客户端读取10个字节,然后写回10个字节,代码如下:

服务器:

#include <iostream>
using namespace std;

#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
using namespace boost;
using namespace boost::asio;
using namespace boost::asio::ip;
namespace ba=boost::asio;

#define SERVER_PORT 12345
#define DATA_LEN 10


struct session : public std::enable_shared_from_this<session>
{
    tcp::socket socket_;
    boost::asio::steady_timer timer_;
    boost::asio::strand<boost::asio::io_context::executor_type> strand_;

    explicit session(boost::asio::io_context& io_context, tcp::socket socket)
    : socket_(std::move(socket)),
      timer_(io_context),
      strand_(io_context.get_executor())
    { }

    void go()
    {
        auto self(shared_from_this());
        boost::asio::spawn(strand_, [this, self](boost::asio::yield_context yield)
        {
            spawn(yield, [this, self](ba::yield_context yield) {
                timer_.expires_from_now(10s); // 10 second
                while (socket_.is_open()) {
                    boost::system::error_code ec;
                    timer_.async_wait(yield[ec]);
                    // timeout triggered, timer was not canceled
                    if (ba::error::operation_aborted != ec) {
                        socket_.close();
                    }
                }
            });

            try
            {
                // read 10 bytes
                string packet;
                boost::system::error_code ec;
                ba::async_read(socket_,
                               ba::dynamic_buffer(packet),
                               ba::transfer_exactly(DATA_LEN),
                               yield[ec]);


                // write 10 bytes
                static string pkt(10, 'a');
                boost::system::error_code ecw;
                boost::asio::write(socket_, boost::asio::buffer(pkt), ecw);
            }
            catch (...)
            {
                cout << "exception" << endl;
            }

            // Sleep(1000); // any better way than Sleep?
            timer_.cancel();
            socket_.close();
        });

    }
};

int main() {
    ba::io_context io_context;
    auto worker = ba::make_work_guard(io_context);

    std::thread([&]()
    {
        tcp::acceptor acceptor(io_context,
        tcp::endpoint(tcp::v4(), SERVER_PORT));

        for (;;)
        {
            boost::system::error_code ec;

            tcp::socket socket(io_context);
            acceptor.accept(socket, ec);
            if (!ec) {
                std::make_shared<session>(io_context, std::move(socket))->go();
            } 
        }
    }).detach();

    io_context.run();
}
#包括
使用名称空间std;
#包括
#包括
#包括
使用名称空间boost;
使用名称空间boost::asio;
使用名称空间boost::asio::ip;
名称空间ba=boost::asio;
#定义服务器端口12345
#定义数据\u LEN 10
结构会话:public std::从\u中启用\u共享\u
{
tcp::socket-socket;
升压::asio::稳定定时器;
boost::asio::串;
显式会话(boost::asio::io_上下文&io_上下文,tcp::socket)
:套接字(标准::移动(套接字)),
计时器(io上下文),
串(io_上下文。get_executor())
{ }
void go()
{
自动自我(从_this()共享_);
boost::asio::spawn(strand_u,[this,self](boost::asio::yield_上下文yield)
{
繁殖(产量[这个,自我](ba::产量\上下文产量){
计时器从现在开始(10秒);//10秒
while(套接字打开(){
boost::system::error_code ec;
定时器异步等待(收益率[ec]);
//超时已触发,计时器未取消
if(ba::error::operation_aborted!=ec){
插座关闭();
}
}
});
尝试
{
//读取10字节
字符串包;
boost::system::error_code ec;
ba::异步读取(套接字读取,
ba::动态缓冲区(数据包),
ba::准确传输(数据长度),
产量[ec];
//写入10个字节
静态字符串pkt(10,'a');
boost::system::错误代码ecw;
boost::asio::write(套接字、boost::asio::buffer(pkt)、ecw);
}
捕获(…)
{

为什么不简单地保持套接字打开直到远程端关闭它呢?当远程端关闭套接字时,你的端将变得可读,“读取”操作将返回零字节读取。添加boost版本,编译器。无法使用
gcc编译代码(Ubuntu 7.4.0-1ubuntu1~18.04.1)7.4.0
boost-1.65.1
@Someprogrammerdude,谢谢。我在(1){async_read(100_字节)}
完成实际作业后,在出现异常之前,关闭套接字,似乎可以正常工作:)为什么不简单地保持套接字打开,直到远程端关闭它?当远程端关闭套接字时,您的端将变得可读,并且“读取”操作将返回零字节读取。添加boost版本,编译器。无法使用
gcc编译代码(Ubuntu 7.4.0-1ubuntu1~18.04.1)7.4.0
boost-1.65.1
@Someprogrammerdude,谢谢。我在(1){async_read(100_字节)}完成实际作业后,在出现异常之前,关闭套接字,似乎可以正常工作:)
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using namespace std;

using boost::asio::ip::tcp;
namespace ba=boost::asio;

#define SERVER "11.22.33.44" // replace with your external ip address
#define PORT "12345"


static string pkt = "1234567890"; // 10 bytes

int main() {
    boost::asio::io_context io_context;

    while(1) {
        getchar();

        try {
            tcp::socket s(io_context);
            tcp::resolver resolver(io_context);
            boost::asio::connect(s, resolver.resolve(SERVER, PORT));

            // write 10 bytes
            boost::system::error_code ecw;
            ba::write(s, ba::buffer(pkt), ecw);

            // read 10 bytes
            string packet;
            boost::system::error_code ec;
            ba::read(s,
                   ba::dynamic_buffer(packet),
                   ba::transfer_exactly(10),
                   ec);

            // client close socket first
            {
                boost::system::error_code ec;
                s.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
                s.close();
            }
        } catch (...) {
            cout << "exception" << endl;
        }

        cout << "done" << endl;
    }
    return 0;
}