C++ boost ptree segmentation fault in multiplayer server with Unity client

nsc4cvqm  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(115)

我正在用nodejs和C的2个服务器构建一个完整的多人应用程序,C服务器的问题是,一旦来自Unity客户端的客户端连接并发送用户数据,服务器就会出现分段故障,并且没有任何消息就退出。
我使用HTTP TCP协议进行通信,并使用下面的代码作为主要功能

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

    std::string raw_ip_address = "0.0.0.0";
    boost::system::error_code ec;

    boost::asio::ip::address ip_address =
        boost::asio::ip::address::from_string(raw_ip_address, ec);

    if (ec.value() != 0) {
        // Provided IP address is invalid. Breaking execution.
        std::cout
            << "Failed to parse the IP address. Error code = "
            << ec.value() << ". Message: " << ec.message();
        return ec.value();
    }
    tcp::endpoint tp(ip_address, 8081);

    tcp::acceptor acceptor(io_context, tp);

    Rooms MainRooms;

    while (true) {
        tcp::socket socket(io_context);
        acceptor.accept(socket);

        RouteRequest(socket, MainRooms);
    }
    return 0;
}

我不能用 Postman 重现这个问题。

void RouteRequest(tcp::socket& socket, Rooms& rooms) {
    std::string route = "/";
    std::string Method;
    //this is always set to process this 
    //better to use json everywhere
    //easier to hack too
    //hopefully security stuff can work here
    std::string request_data = BufferToString(socket, route, Method);

    //std::cout << Method << "THis is method" << std::endl;
    //std::cout << route << "THis is Route" << std::endl;
    //std::cout << request_data << std::endl;+      Current {username="" accessToken="" Room=0 ...} Player

    //always send a response
    std::string response;

    if (Method.compare("POST") == 0) {
        if (route.compare("/") == 0) {
            try
            {
                Player Current = Player(request_data);
                if (rooms.addRoomMate(Current)) {
                    sendHttpResponse(response, 200, "text/html", "Person Added!");
                    Current.printDetails();
                }
                else {
                    sendHttpResponse(response, 200, "text/html", "Person Exists!");
                }
            }
            catch (const std::exception& e)
            {
                throw e.what();
                std::cout << e.what() << std::endl;
                sendHttpResponse(response, 500, "text/html", e.what());
            }
        }

似乎有时候request_data没有它的json
我尝试在发送之前、传输期间和到达C++服务器之后检查值。发送前:在C#客户端中,代码是:

private IEnumerator Post(string url, string bodyJsonString)
    {
        var request = new UnityWebRequest(URL + url, "POST");
        byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString);
        request.uploadHandler = new UploadHandlerRaw(bodyRaw);

        //Debug.Log(Encoding.ASCII.GetString(bodyRaw));

        request.downloadHandler = new DownloadHandlerBuffer();

        request.SetRequestHeader("Content-Type", "application/json");
        yield return request.SendWebRequest();

        //Debug.Log("Status Code: " + request.responseCode);
        //Debug.Log(request.downloadHandler.text);
    }
    private void SendWithDetails()
    {
        SendData();
        string json = JsonUtility.ToJson(ThisData);
        Debug.Log("Sending");
        Debug.Log(json);

       StartCoroutine(Post("update", json));
    }
    private void FixedUpdate()
    {
        if (isLoggedIn == true)
        {
            SendWithDetails();
        }
    }
    void SendData()
    {
        //we just need w and y
        float x =ThisPlayer.transform.position.x;
        float y = ThisPlayer.transform.position.y;
        float z = ThisPlayer.transform.position.z;
        float v = ThisPlayer.transform.eulerAngles.x;
        float u = ThisPlayer.transform.eulerAngles.y;
        float w = ThisPlayer.transform.eulerAngles.z;

        x = Mathf.FloorToInt(1000 * x) / 1000;
        y = Mathf.FloorToInt(1000 * y) / 1000;
        z = Mathf.FloorToInt(1000 * z) / 1000;
        u = Mathf.FloorToInt(1000 * u) / 1000;
        v = Mathf.FloorToInt(1000 * v) / 1000;
        w = Mathf.FloorToInt(1000*x)/1000;

        Debug.Log("Added data");
        ThisData.QuickAssign(x, y, z, u, v, w);
    }

我检查了所有的变量和字节数组都是完全正确的。
然后在运输过程中我用Wireshark检查了一下,没有问题。我用来从套接字获取json字符串的函数是

std::string BufferToString(tcp::socket& socket, std::string& route, std::string& Method) {

    boost::asio::streambuf request_buffer;
    boost::system::error_code error;

    try
    {
        boost::asio::read_until(socket, request_buffer, "\r\n\r\n", error);
        if (error) {
            throw std::runtime_error(error.message()); // Rethrow the error as an exception
        }
    }
    catch (const std::exception& ex)
    {
        std::cout << "Exception occurred: " << ex.what() << std::endl;
        return " ";
    }

    std::string request_data(boost::asio::buffers_begin(request_buffer.data()),
        boost::asio::buffers_end(request_buffer.data()));

    std::size_t path_start = request_data.find(" ");
    if (path_start != std::string::npos) {
        std::size_t path_end = request_data.find(" ", path_start + 1);
        route = request_data.substr(path_start + 1, path_end - path_start - 1);
    }
    else {
        std::cout << "String error: \n" << request_data << std::endl;
    }

    Method = request_data.substr(0, request_data.find(" "));

    return request_data;
}
nbewdwxp

nbewdwxp1#

std::string函数find()给了start_pos变量一个不自然的值。同时request_data也会有一个空的函数体。我使用的代码是:

std::string BufferToString(tcp::socket& socket, std::string& route, std::string& Method) {

boost::beast::flat_buffer request_buffer;
boost::beast::http::request<boost::beast::http::string_body> request;
boost::system::error_code error;

try
{
    boost::beast::http::read(socket, request_buffer, request, error);
    if (error) {
        throw std::runtime_error(error.message()); // Rethrow the error as an exception
    }
}
catch (const std::exception& ex)
{
    std::cout << "Exception occurred: " << ex.what() << std::endl;
    return " ";
}

Method = request.method_string();
route = request.target();

std::string request_data = request.body();
return request_data;}

这使用了内置的解析器,并处理了我可能遇到的任何内存问题(我无法解决)

相关问题