我在下面的代碼中遇到了一些問題。它旨在從服務器接收文件。只要服務器在發送後斷開連接,它就可以100%正常工作。如果服務器斷開,文件傳輸纔會完成
如果服務器沒有斷開連接,那麼傳輸不會完成客戶端,並且客戶端繼續等待字節並且不會正確地跳出循環(當fr_block_sz == 0時),因爲它服務器在收到文件後斷開連接。它無休止地坐在循環中。
我希望能夠接收文件並保持連接打開後。有什麼建議?謝謝。
編輯:根據凱西的建議我現在正在監視通過下面的註釋代碼寫入的字節數量,但得到奇怪的行爲導致文件傳輸未正確完成。任何人都可以在我的代碼中看到任何錯誤嗎?謝謝。
編輯2:我發佈了關於我的問題的調試信息,試圖使其更清晰。
// Reciever of file (client)
int TotalSize = 7374; // hardcoded file size to expect
int FileSize = 0; // counter
int fr_block_sz = 0;
while ((fr_block_sz = recv(sd, revbuf, 1, 0)) > 0) //LENGTH == 512
{
if (fr_block_sz < 0)
if (errno == EAGAIN)
continue;
else
printf("File write failed");
if (fr_block_sz == 0)
break; //done
// edit based on comment - does not change behavior
if(FilzeSize > TotalSize)
{
fr_block_sz = fr_block_sz - (FileSize - TotalSize);
}
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
// add total bytes recvd every loop
FileSize += write_sz;
// if bytes recieved equals expect file size, break
if (FileSize >= TotalSize)// this is where my problem is, as sometimes
// FileSize == 7376 or 7672 instead of 7374
// When it fails, fr_block_sz == 24 which
// i don't think is right either. Even when
// set to break if FileSize > TotalSize, the
// loop still doesn't complete
break;
printf("Recieved size == %i of %i \n", FilzeSize, TotalSize);
if (write_sz < fr_block_sz)
{
printf("File write failed");
}
bzero(revbuf, 1);
}
printf("Transfer complete \n");
控制檯輸出:
Recieved size == 512 of 7374
Recieved size == 1024 of 7374
Recieved size == 1368 of 7374
Recieved size == 1880 of 7374
Recieved size == 2392 of 7374
Recieved size == 2736 of 7374
Recieved size == 3248 of 7374
Recieved size == 3760 of 7374
Recieved size == 4104 of 7374
Recieved size == 4616 of 7374
Recieved size == 5128 of 7374
Recieved size == 5472 of 7374
Recieved size == 5984 of 7374
Recieved size == 6496 of 7374
Recieved size == 6840 of 7374
Recieved size == 7352 of 7374
Recieved size == 7376 of 7374
一旦它送過來,客戶端將永遠等待在這裏的循環,沒有任何反應。然後我必須從控制檯手動停止程序,並且在程序停止後,只有4096個字節的文件被寫入。如果有人能夠闡明我的問題,或者說「正常」的方式來做到這一點,我會非常感激。謝謝。
編輯 - 固定(有點)。我發現一種方法可以使其每次可靠地工作100%,即通過更改LENGTH == 1,因此設置一個字節的緩衝區大小,並且如果內核正在爲字節寫入字節,則無法獲得短/長讀取。這可行,但顯然不是最快的解決方案。我仍然希望聽到其他人的聲音,並感謝你的幫助拉賈爾。
所以,你必須看看服務器代碼,而不是 – bbonev
無關:填充用零的緩衝器你與其他數據填充它之前,是沒有意義的。 – Casey
凱西 - 固定,bbonev - 模糊評論,跟進。 – 4r4r4r