我正在用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;
}
1条答案
按热度按时间nbewdwxp1#
std::string函数find()给了start_pos变量一个不自然的值。同时request_data也会有一个空的函数体。我使用的代码是:
这使用了内置的解析器,并处理了我可能遇到的任何内存问题(我无法解决)