Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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::async_写入导致错误现有连接被远程主机强制关闭_C++_Boost_Boost Asio - Fatal编程技术网

C++ boost::async_写入导致错误现有连接被远程主机强制关闭

C++ boost::async_写入导致错误现有连接被远程主机强制关闭,c++,boost,boost-asio,C++,Boost,Boost Asio,我想使用boost::asio将结构从客户端发送到服务器。我遵循了boost教程链接。我稍微修改了server.cpp和client.cpp中的代码。使用新代码,在建立连接后,client.cpp将结构stock写入服务器并读取服务器端的stock信息。(在教程版本中,建立连接后,服务器将stock struct写入客户端,客户端读取它们。此版本适用于我。) 我的问题是,建立连接后,client.cpp中的async\u write会导致错误 写入错误:远程主机强制关闭了现有连接 而server

我想使用
boost::asio
将结构从客户端发送到服务器。我遵循了boost教程链接。我稍微修改了
server.cpp
client.cpp
中的代码。使用新代码,在建立连接后,
client.cpp
将结构stock写入服务器并读取服务器端的stock信息。(在教程版本中,建立连接后,服务器将stock struct写入客户端,客户端读取它们。此版本适用于我。)

我的问题是,建立连接后,
client.cpp
中的
async\u write
会导致错误

写入错误:远程主机强制关闭了现有连接

server.cpp
中的
async\u read
会导致错误

读取错误:本地系统中止了网络连接

正如一些论坛答案所建议的,我将async_write和async_read函数处理程序中的
this
指针从this更改为
shared_。问题仍然存在

我无法确定是客户端还是服务器端导致了问题。请帮忙

server.cpp

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <vector>
#include "connection.h" // Must come before boost/serialization headers.
#include <boost/serialization/vector.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "stock.h"

namespace s11n_example
{
    /// Serves stock quote information to any client that connects to it.
    class server : public boost::enable_shared_from_this<server>
    {
        private:
            /// The acceptor object used to accept incoming socket connections.
            boost::asio::ip::tcp::acceptor acceptor_;
            /// The data to be sent to each client.
            std::vector<stock> stocks_;

        public:
            /// Constructor opens the acceptor and starts waiting for the first incoming
            /// connection.
            server(boost::asio::io_service& io_service, unsigned short port):
            acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
            {
                // Start an accept operation for a new connection.
                connection_ptr new_conn(new connection(acceptor_.get_io_service()));
                acceptor_.async_accept(new_conn->socket(),
                    boost::bind(&server::handle_accept, this,boost::asio::placeholders::error, new_conn));
            }

            /// Handle completion of a accept operation.
            void handle_accept(const boost::system::error_code& e, connection_ptr conn)
            {
                if (!e)
                {
                    std::cout <<  "Received a connection" <<std::endl;
                    conn->async_read(stocks_,
                         boost::bind(&server::handle_read, shared_from_this(),boost::asio::placeholders::error));
                }
                // Start an accept operation for a new connection.
                connection_ptr new_conn(new connection(acceptor_.get_io_service()));
                acceptor_.async_accept(new_conn->socket(),
                    boost::bind(&server::handle_accept, this,boost::asio::placeholders::error, new_conn));
            }
            /// Handle completion of a read operation.
            void handle_read(const boost::system::error_code& e)
            {
                if (!e)
                {
                    // Print out the data that was received.
                    for (std::size_t i = 0; i < stocks_.size(); ++i)
                    {
                        std::cout << "Stock number " << i << "\n";
                        std::cout << "  code: " << stocks_[i].code << "\n";
                        std::cout << "  name: " << stocks_[i].name << "\n";
                        std::cout << "  open_price: " << stocks_[i].open_price << "\n";
                        std::cout << "  high_price: " << stocks_[i].high_price << "\n";
                        std::cout << "  low_price: " << stocks_[i].low_price << "\n";
                        std::cout << "  last_price: " << stocks_[i].last_price << "\n";
                        std::cout << "  buy_price: " << stocks_[i].buy_price << "\n";
                        std::cout << "  buy_quantity: " << stocks_[i].buy_quantity << "\n";
                        std::cout << "  sell_price: " << stocks_[i].sell_price << "\n";
                        std::cout << "  sell_quantity: " << stocks_[i].sell_quantity << "\n";
                    }
                }
                else
                {
                    // An error occurred.
                    std::cerr << "Error in read:" << e.message() << std::endl;
                }
            }
    };

} // namespace s11n_example
int main(int argc, char* argv[])
{
    try
    {
        // Check command line arguments.
        if (argc != 2)
        {
            std::cerr << "Usage: server <port>" << std::endl;
            return 1;
        }
        unsigned short port = boost::lexical_cast<unsigned short>(argv[1]);

        boost::asio::io_service io_service;
        boost::shared_ptr<s11n_example::server> server(new s11n_example::server(io_service, port));
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括“connection.h”//必须在boost/serialization头之前。
#包括
#包括
#包括“stock.h”
名称空间s11n_示例
{
///将股票报价信息提供给任何连接到它的客户端。
类服务器:public boost::从\u启用\u共享\u
{
私人:
///用于接受传入套接字连接的接受器对象。
boost::asio::ip::tcp::acceptor-acceptor;
///要发送到每个客户端的数据。
std::病媒股票;
公众:
///构造函数打开接受程序并开始等待第一个传入的
///连接。
服务器(boost::asio::io_服务和io_服务,未签名短端口):
接受者(io_服务,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),端口))
{
//启动新连接的接受操作。
连接(新连接(接受器获取io服务());
acceptor_u.async_uAccept(新连接->套接字(),
boost::bind(&server::handle_accept,this,boost::asio::placeholders::error,new_conn));
}
///处理接受操作的完成。
无效句柄\u接受(常量boost::系统::错误\u代码和e,连接\u ptr conn)
{
如果(!e)
{

std::cout您需要传递
conn
来处理读取,否则它将在
handle\u accept
方法的末尾被破坏。当它被破坏时,它包含的套接字也将被破坏,连接将关闭

conn->async_read(stocks_,
     boost::bind(&server::handle_read, shared_from_this(), conn, boost::asio::placeholders::error));
lambda比使用bind更易于阅读:

auto self = shared_from_this();
conn->async_read(stocks_,
[self, this, conn] (boost::system::error_code ec) { handle_read(ec); });
将复制捕获列表中列出的变量,以使共享指针保持活动状态

auto self = shared_from_this();
conn->async_read(stocks_,
[self, this, conn] (boost::system::error_code ec) { handle_read(ec); });