我使用Linux套接字API实现了一个HTTP服务器,我创建的功能之一是文件传输。
我encouter的问题是当我试图传输png/jpeg文件.写入二进制文件数据后,文件被损坏,它不能被打开.对于PDF为ex.它的工作完美.
这是我处理HTTP请求的方式:
首先,我使用以下函数接收请求。这里我将接收到的缓冲区传递给HTTPrequestsException:
template <typename T>
void server::printReceivedData(class acceptedSocket<T> *socket)
{
T buffer[1025];
int acceptedSocketFD = socket->getAcceptedSocketFileDescriptor();
while (true)
{
ssize_t bytesReceived = recv(acceptedSocketFD, buffer, sizeof(buffer), 0);
if (bytesReceived <= 0)
{
std::cerr << "Receive failed! "
<< socket->getError() << "\n";
std::string file = __user->getFileInQueue();
if (!file.empty())
{
addToFileTable(file.c_str(), 0);
__user->clearFileInQueue();
if (send(acceptedSocketFD, "HTTP/1.1 302 Found\r\nLocation: /index.html\r\nConnection: close\r\n\r\n", 65, 0) == -1)
std::cerr << "Failed to send response.\n";
}
break;
}
std::cout << "\n____________________________________________________________\n\n";
buffer[bytesReceived] = '\0';
std::cout << buffer;
HTTPrequestsHandler<T>(buffer, acceptedSocketFD, bytesReceived);
}
close(socket->getAcceptedSocketFileDescriptor());
delete socket;
}
字符串
在HTTPrequestHandle函数中,我将缓冲区转发到正确的路由函数(在本例中为**/addFileRoute**):
int user::addFilesRoute(const char *buffer, int acceptedSocketFileDescriptor, ssize_t __bytesReceived)
{
if (findString(buffer, "filename="))
{
fileName.clear();
path.clear();
path = "interface/storage/";
const std::string t_buffer = std::string(buffer);
std::regex fileNameRegex(R"(filename=\"([^\"]+)\")");
std::smatch match;
if (std::regex_search(t_buffer, match, fileNameRegex))
fileName = match.str(1);
path = path + fileName;
addFileInQueue(fileName);
}
std::ofstream file(path, std::ios::out | std::ios::app | std::ios::binary);
if (file.is_open())
{
file.write(buffer, __bytesReceived);
file.close();
}
return EXIT_SUCCESS;
}
型
在这里,我用正确的文件名将文件数据写入文件中。
我添加的所有文件都成功地写入了我计算机上的一个文件,但图像文件无法打开。
addFileInQueue=准备文件名推送到数据库的函数
filename=保存当前HTTP请求的文件名的全局变量
path=用于将文件保存到正确位置的全局变量
我尝试了不同的方法来格式化文件数据。一种是删除所有请求中额外的头,但这会破坏所有内容。
!请记住,缓冲区有1025字节的数据块,而不是孔请求
谢谢你的帮助!
1条答案
按热度按时间m2xkgtsf1#
我设法解决了这个问题:
1.我修改了addFileroute函数,直接将数据写为uint8_t类型(我将去掉**char buffer*,只在本地重新转换)
字符串
1.我将数据写入一个temp.bin文件,在收到请求后,我处理它。(最后我删除temp.bin文件)
型