我有一个用 C++ 编写的 TCP 服务器和客户端的 React.js 应用程序。
您需要知道的是
定义向客户端发送数据的逻辑的类方法:
void TcpServer::sendDataToClient()
{
nlohmann::json jsonData = readData();
std::string jsonDataStr = jsonData.dump();
if (jsonData.empty())
{
log("No data to send to client.\n\n");
return;
}
std::string headers =
"HTTP/1.1 200 OK\r\n"
"Content-Type: application/json; charset=utf-8\r\n"
"Access-Control-Allow-Origin: *\r\n"
"Content-Length: " + std::to_string(jsonDataStr.size()) + "\r\n"
"Connection: close\r\n"
"\r\n";
send(m_new_socket, headers.c_str(), headers.size(), 0);
send(m_new_socket, jsonDataStr.c_str(), jsonDataStr.size(), 0);
log("------ Data sent to client ------\n\n");
}
缓冲区大小和 CORS:
namespace
{
const int BUFFER_SIZE = 500000000;
void log(const std::string& message)
{
std::cout << message << std::endl;
}
void exitWithError(const std::string& errorMessage)
{
std::cout << WSAGetLastError() << std::endl;
log("ERROR: " + errorMessage);
exit(1);
}
void setCorsHeaders(SOCKET clientSocket)
{
const char* headers =
"HTTP/1.1 200 OK\r\n"
"Content-Type: application/json\r\n"
"Access-Control-Allow-Origin: *\r\n"
"Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS\r\n"
"Access-Control-Allow-Headers: Content-Type\r\n"
"Content-Length: 0\r\n"
"Connection: close\r\n"
"\r\n";
send(clientSocket, headers, strlen(headers), 0);
}
}
这就是我向 C++ 服务器发送 GET 请求的方式:
const handleFetchServer = async () => {
try {
const response = await axios.get('http://127.0.0.1:5174')
console.log('Response:', response)
console.log('Data from server:', response.data)
} catch (error) {
console.error('Error fetching data: ', error)
}
}
1.数据准确地存储在 jsonDataStr 变量中
2.没有编译器或链接器错误
3. 一切正常,只是在向客户端发送数据时发送的是空字符串,而不是 jsonDataStr 变量中的数据
4. 在客户端上,我得到一个空字符串 - GET 请求本身以代码 200 执行,这意味着服务器响应并且一切都成功。
5.我还尝试将一个非常小的字符串从服务器传递到客户端,但我再次看到一个空字符串
我解决了这个问题。
重点是我没有注意到 GET 请求是如何处理的。 一般来说,这是之前处理请求的函数:
void TcpServer::handleRequest(const std::string& request)
{
if (request.find("GET /user_data.json HTTP/1.1") != std::string::npos)
{
//GET
sendDataToClient();
}
else if (request.find("POST /user_data.json HTTP/1.1") != std::string::npos)
{
//POST
std::cout << "POST\n\n" << std::endl;
size_t start = request.find("{");
if (start != std::string::npos)
{
std::string jsonData = request.substr(start);
writeData(jsonData);
}
}
}
我对一个不需要的 GET 请求进行了测试响应,我一开始就这样做了,以检查服务器的响应。 他正处于无尽的听众循环中:
void TcpServer::startListen()
{
if (listen(m_socket, 20) < 0)
{
exitWithError("Socket listen failed");
}
std::ostringstream ss;
ss << "\n*** Listening on ADDRESS: " << inet_ntoa(m_socketAddress.sin_addr) << " PORT: " << ntohs(m_socketAddress.sin_port) << " ***\n\n";
log(ss.str());
int bytesReceived;
while (true)
{
log("====== Waiting for a new connection ======\n\n\n");
acceptConnection(m_new_socket);
char* buffer = new char[BUFFER_SIZE];
bytesReceived = recv(m_new_socket, buffer, BUFFER_SIZE, 0);
if (bytesReceived < 0)
{
exitWithError("Failed to receive bytes from client socket connection");
}
std::ostringstream ss;
ss << "------ Received Request from client ------\n\n";
log(ss.str());
sendResponse();
std::string requestData(buffer);
handleRequest(requestData);
delete[] buffer;
closesocket(m_new_socket);
}
}
它被称为:
sendResponse();
因此,当客户端向服务器请求数据时,首先收到的就是该函数的响应,然后发送需要的数据,但由于客户端已经收到了响应,所以干脆不接受以下数据。
为了检测此问题,我使用了 Wireshark 实用程序。
这是我修改后的请求处理函数:
void TcpServer::handleRequest(const std::string& request)
{
if (request.find("GET /user_data.json HTTP/1.1") != std::string::npos)
{
//GET
sendDataToClient();
}
else if (request.find("POST /user_data.json HTTP/1.1") != std::string::npos)
{
//POST
std::cout << "POST\n\n" << std::endl;
size_t start = request.find("{");
if (start != std::string::npos)
{
std::string jsonData = request.substr(start);
writeData(jsonData);
}
}
else if (request.find("GET / HTTP/1.1") != std::string::npos)
{
sendResponse();
}
else
{
log("Unknown request.\n\n");
}
}