Я новичок в серверной разработке, но знаю много вещей из фронтенд-разработки.
Моя проблема:
1. Со стороны клиента (приложение React.js) строка JSON отправляется (POST-запрос) на C++-сервер:
const handleFetchData = async () => {
try {
dispatch(setRepoUrl(inputUrl))
const urlParts = inputUrl.split('/')
const username = urlParts[3]
const repo = urlParts[4]
const response = await axios.get(
`https://api.github.com/repos/${username}/${repo}/issues`
)
dispatch(setIssues(response.data))
const api_data = JSON.stringify(response.data)
await axios.post('http://127.0.0.1:5174/user_data.json', { api_data })
console.info('Data saved on server:', api_data)
} catch (error) {
console.error('Error fetching data: ', error)
}
}
2. Сервер C++ обрабатывает этот запрос и записывает его в файл, но сначала удаляет существующие данные в файле .json:
void TcpServer::writeData(const std::string& data)
{
remove(user_data_path);
size_t start = data.find("{");
if (start == std::string::npos)
{
std::cerr << "JSON data not found in the input string.\n\n" << std::endl;
return;
}
std::string jsonData = data.substr(start);
std::ofstream file(user_data_path, std::ios::out);
if (file.is_open())
{
file << jsonData << std::endl;
file.close();
std::cout << "Data saved to user_data.json\n\n" << std::endl;
}
else
{
std::cerr << "Failed to open file for writing.\n\n" << std::endl;
}
}
3. После записи строки JSON в файл .json приложение Visual Studio отображает окно со следующим сообщением об ошибке:
Загрузка файла
Некоторые байты были заменены символом замены Unicode при загрузке файла
При сохранении файла исходное содержимое файла не сохраняется
4. После этого некоторые символы в строке JSON преобразуются в это - (\r\n\t\t<Ex1 InternalRef = {ref}>\r\n\t\t\t{дети}\r\n \t\t</Ex1>\r\n\t);\r\n});���������������������������� ������7#�
Возможно кто-то знает в чем проблема и как ее исправить.
В конце концов, мне нужна действительная строка JSON.
P.S. Этот сервер написан для Windows (#include <winsock.h>).
Не хочу вызывать недовольство в комментариях типа "почему он пишет сервер на C++, а не на node.js и т.п."
Я младший фронтенд-разработчик, и мне просто нравится C++, поэтому я выбрал этот язык.
Спасибо за понимание, надеюсь на вашу помощь.
Я долго искал решение проблемы и просто пришел к выводу написать пост по Stack Overflow, поэтому вариантов решения этой проблемы у меня нет.





Проблема заключалась в размере буфера, который составлял 30720 байт.
const int BUFFER_SIZE = 500000000;
Я только что изменил размер, который составляет примерно 500 МБ, и теперь выбираю их из кучи.
char* buffer = new char[BUFFER_SIZE];
Здесь используется буфер, я просто беру из него данные и затем передаю их в качестве аргумента функции, которая записывает эти данные в файл:
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);
}
}
Данные записывались в файл по мере необходимости, поскольку размер буфера не позволял вместить большие данные.
if (bytesReceived < 0) -- Если это произойдет, у вас произойдет утечка памяти. На самом деле, у вас есть утечка памяти, если по какой-либо причине функция startListen выдает исключение и/или не достигает строки delete[]. Используйте правильный класс RAII, который самоочищается. Вместо char* buffer = new char[BUFFER_SIZE]; должно быть std::vector<char> buffer(BUFFER_SIZE);, а затем bytesReceived = recv(m_new_socket, buffer.data(), buffer.size(), 0);. Тогда вызов delete[] можно будет удалить.
С опубликованным вами кодом C++ проблем нет — он получает строку, открывает файл, записывает строку в файл. Что содержит эта строка — это другая история. Что вам нужно сделать, так это использовать отладчик и посмотреть, что именно
dataсодержит при вызовеwriteData. Слишком поздно видеть, что делает Visual Studio. Мой хрустальный шар говорит мне, что вы создалиstd::stringизdata, не используя фактическую длину данных, т. е.std::string data = <whatever>;вместоstd::string data(whatever, length_of_whatever);.