簡體   English   中英

Boost tcp_server async_write錯誤:訪問沖突寫入位置

[英]Boost tcp_server async_write error: access violation writing location

我一直在嘗試使用boost實現一個簡單的tcp服務器,該服務器接受客戶端連接,並通過調用服務器公開的方法將一些信息發送回客戶端。

這是我根據Boost教程創建的類:

#define WIN32_LEAN_AND_MEAN

#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;


#include <ctime>
#include <iostream>
#include <string>

#include "Logger.h"



class tcp_server_connection
    : public boost::enable_shared_from_this<tcp_server_connection>
{
public:
    typedef boost::shared_ptr<tcp_server_connection> pointer;

    static pointer create(boost::asio::io_service& io_service)
    {
        return pointer(new tcp_server_connection(io_service));
    }

    tcp::socket& socket()
    {
        return socket_;
    }

    void start(string message)
    {
        swap(m, message);

        boost::asio::async_write(socket_, boost::asio::buffer(m),
            boost::bind(&tcp_server_connection::handle_write, shared_from_this(),
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
    }

private:
    tcp_server_connection(boost::asio::io_service& io_service)
        : socket_(io_service)
    {
        Logger::Log("main.log", "New TCP Server Connection");
    }


    void handle_write(const boost::system::error_code& error,
        size_t bytes_transferred)
    {
        if (error) {
            Logger::Log("main.log", "TCP Server Write Error: ");
        }
    }

    tcp::socket socket_;
    string m;
};

class tcp_server
{
public:
    tcp_server(boost::asio::io_service& io_service, int port)
        : acceptor_(io_service, tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), port))
    {
        start_accept();
    }

    void write(string message) {
        connection->start(message);
    }

private:
    void start_accept()
    {
        connection = tcp_server_connection::create(acceptor_.get_io_service());

        acceptor_.async_accept(connection->socket(),
            boost::bind(&tcp_server::handle_accept, this, connection,
            boost::asio::placeholders::error));
    }

    void handle_accept(tcp_server_connection::pointer new_connection,
        const boost::system::error_code& error)
    {
        if (!error)
        {
            Logger::Log("main.log", "TCP Server Accepted Connection");
        }
        else {
            Logger::Log("main.log", "TCP Server Error accepting Connection");
        }
    }

    tcp::acceptor acceptor_;
    tcp_server_connection::pointer connection;
};

我通過使用以下方法啟動線程來啟動服務器:

void SetupServer() {
    boost::asio::io_service io_service;
    server = new tcp_server(io_service, serverPort);
    io_service.run();
}

當我想向客戶端寫入內容時,我調用server-> write(“ Some Text”),但是async_write引發異常,並顯示“訪問沖突寫入位置”。 我相信可能應該清理某些對象,但是我不知道為什么在哪里清理,所以如果有人可以讓我對這是為什么以及如何解決有一些見解,我將不勝感激。

預先感謝您的任何幫助。

好吧,我發現問題與以下事實有關:io_service變量是在范圍更改時釋放的,地獄正在崩潰。

為了解決這個問題,我將setupServer更改為:

io_service = new boost::asio::io_service();
rankingServer = new tcp_server(*io_service, serverPort);
io_service->run();

並使用該變量在類中的其他位置聲明該變量:

boost::asio::io_service *io_service = NULL;

請記住,該變量需要釋放,調用

delete io_service;

希望這可以幫助某人。

聽起來您在從主線程調用server-> write(“ Some Text”)。 但是,到目前為止,到目前為止尚未連接任何客戶端,因此您可能嘗試在沒有連接端點的套接字上進行寫操作。 甚至可能是io_service線程尚未啟動的情況。

使用boost asio編寫異步程序時,通常會啟動一個異步操作並傳遞一個處理程序,一旦請求的操作成功(或失敗),該處理程序將被調用。 在那里您可以做出反應,例如鏈接另一個異步動作。 在您的示例中,成功連接客戶端后,將在不設置錯誤代碼的情況下調用tcp_server :: handle_accept()處理函數。 在這里放置調用write(“ Some Text”)。

根據您的問題,在我看來,您想觸發從io_service線程“外部”寫入數據。 使用多個線程時,請小心。 嘗試從“主”線程和運行io_service的線程(以及所有異步處理程序)訪問數據時,請確保使用適當的鎖定。 另外,請注意比賽條件,不要依賴計算機或操作系統的時間安排或時間表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM