【发布时间】:2025-12-24 12:55:06
【问题描述】:
我正在学习 boost::asio 网络编程,并尝试使用阻塞套接字进行简单的文件传输练习,因此遇到了奇怪的问题。
服务器(接收器)循环如下:
while (true){
int bufSize{ static_cast<int>(pow(2, 18)) };
char* buf{ new char[bufSize] };
__int64 currPos{ 0 };
__int64 fileSize;
std::string fileName;
mSocket->receive(buffer(buf, bufSize)); // here we get pre-defined packet with XML
ParseDescXML(std::string{ buf }, &fileName, &fileSize); // and parse this XML, get name and size
std::ofstream ofs(mSavePath + fileName, std::ios::binary);
if (ofs.is_open()){
while (currPos != fileSize) {
if (bufSize > fileSize - currPos){
delete[] buf;
bufSize = fileSize - currPos;
buf = new char[bufSize];
}
mSocket->receive(buffer(buf, bufSize));
ofs.write(buf, bufSize);
currPos += bufSize;
std::cout << "SERVER " << currPos << std::endl;
}
}
delete[] buf;
ofs.close();
slDebug("Receive completed"); // output some stuff, not related to issue
}
客户端(发送者)循环如下:
mWorkerOccupied = true;
std::ifstream ifs(filePath, std::ios::binary);
if (!ifs.is_open()){
mWorkerOccupied = false;
return false;
}
mFileName = filePath.substr(filePath.find_last_of('\\') + 1, filePath.length());
mCurrPos = 0;
mFileSize = GetFileSize(&ifs);
std::string xmlDesc{ MakeXMLFileDesc(mFileName, mFileSize) }; // here we make XML description
xmlDesc.push_back('\0');
int bufSize{ static_cast<int>(pow(2, 18)) };
char* buf{ new char[bufSize] };
mSocket->send(buffer(xmlDesc.c_str(), bufSize)); // and send it.
while (mCurrPos != mFileSize){
if (bufSize > mFileSize - mCurrPos){
delete[] buf;
bufSize = mFileSize - mCurrPos;
buf = new char[bufSize];
}
ifs.read(buf, bufSize);
mSocket->send(buffer(buf, bufSize));
mCurrPos += bufSize;
std::cout << "CLIENT " << mCurrPos << std::endl;
}
ifs.close();
delete[] buf;
mWorkerOccupied = false;
slDebug("SendFile completed");
所有这些东西都在并行线程中运行。 据我了解,它应该以这种方式工作:
- 服务器线程运行服务器并挂起,直到传入连接(按预期工作,所以我没有在此处包含此代码)。
- 客户端线程在一段时间后运行并连接到服务器(按预期工作)
- 服务器等待第一个数据包,包含 XML(按预期工作)
- 客户端发送 XML,服务器获取它(按预期工作)
- 客户端开始发送实际的二进制数据,服务器得到它。这是我们遇到的主要问题。
我在客户端和服务器循环中都有文件当前位置的输出。 我希望它是这样的:
CLIENT 228 // first we send some data
SERVER 228 // Server gets it and outputs the same file pos
或
CLIENT 228
CLIENT 456
SERVER 228
SERVER 456
但我实际得到的 - 让我感到困惑......
SERVER 499384320
SERVER 499646464
CLIENT 88604672
SERVER 499908608
CLIENT 88866816
SERVER 500170752
SERVER 500432896
SERVER 500695040
SERVER 500957184
关于通过服务器接收东西的消息比关于发送的客户端消息要多得多。怎么可能?从字面上看,看起来客户端只发送了 80mb 的数据,而服务器已经收到了 500mb 的数据......我想,服务器线程应该等待接收(),因为我使用的是阻塞套接字,但这很奇怪。谁能解释一下,为什么我有这么大的不同步?
【问题讨论】:
标签: c++ sockets boost-asio ifstream ofstream