2014-11-05 141 views
1

我正在學習boost :: asio網絡編程,並試圖進行簡單的文件傳輸練習,使用阻塞套接字,所以,困在奇怪的問題問題。使用boost :: asio編寫簡單的文件傳輸程序。有主要發送接收desync

服務器(接收器)循環如下:

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"); 

所有這些東西是在平行線程中運行。 從我的理解應該以這種方式工作:

  1. 服務器的線程中運行服務器和掛起,直到傳入的連接(如預期工作,所以我在這裏沒有包含這些代碼)。
  2. 客戶線程一段時間後運行並連接到服務器(按預期工作)
  3. 服務器等待第一個數據包,包含XML(按預期工作)
  4. 客戶端發送XML,服務器得到它(按預期工作)
  5. 客戶端開始發送實際的二進制數據,服務器得到它。這裏我們遇到重大問題。

我在客戶端和服務器端都有文件當前位置的輸出。 我希望它是這樣的:

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的數據......我想,服務器線程應該等待receive(),因爲我使用的是阻塞套接字,但這很奇怪。有人可以解釋我,爲什麼我有這個巨大的異步?

回答

3

你假設receive讀取整個緩衝區大小一次,但它不一定:

The receive operation may not receive all of the requested number of bytes. Consider using 
the read function if you need to ensure that the requested amount of data is read before the 
blocking operation completes 

receive返回的數據量讀取,您應該更改您的代碼是這樣的:

size_t recvd = mSocket->receive(buffer(buf, bufSize)); 
ofs.write(buf, recvd); 
currPos += recvd; 
相關問題