我使用C#爲Windows和Java創建服務器軟件來創建客戶端軟件。 大部分時間都能正常工作,除了那些我不明白的少數例外。TCP發送/接收丟失字節
我通常使用.ReadLine()和.WriteLine()兩端進行通信,除非我嘗試發送二進制數據。那是我直接寫和讀字節的時候。 這是軟件應該如何工作:
- 客戶端請求的二進制數據
- 服務器響應與二進制數據的長度爲
- 客戶端收到的長度,並將其轉換成整數,字符串開始讀(長度)字節
- 服務器開始寫(長度)字節
它工作在大多數情況下,但有時客戶端應用程序不會收到完整的數據和b鎖。服務器在寫入數據後總是立即刷新,所以刷新不是問題。
此外我已經注意到這通常發生在較大的文件,小文件(高達〜1 MB)通常不是問題。
注意似乎C#服務器完全發送數據,所以問題很可能在Java代碼的某處。
編輯 - 以下是從客戶端
工作的一些日誌下載:pastebin.com/hFd5TvrF
好像客戶在等待2048個字節最後(在這種情況下應該是length - processed = 2048
),但由於某種原因客戶端阻塞。
任何想法我做錯了什麼?下面是服務器和客戶端的源代碼:
C#服務器:
public void Write(BinaryWriter str, byte[] data)
{
int BUFFER = 2048;
int PROCESSED = 0;
// WriteString sends the String using a StreamWriter (+ flushing)
WriteString(data.Length.ToString());
while (PROCESSED < data.Length)
{
if (PROCESSED + BUFFER > data.Length)
BUFFER = data.Length - PROCESSED;
str.Write(data, PROCESSED, BUFFER);
str.Flush();
PROCESSED += BUFFER;
}
}
Java客戶端:
public byte[] ReadBytes(int length){
byte[] buffer = new byte[length];
int PROCESSED = 0;
int READBUF = 2048;
TOTAL = length;
progress.setMax(TOTAL);
InputStream m;
try {
m = clientSocket.getInputStream();
while(PROCESSED < length){
if(PROCESSED + READBUF > length)
READBUF = length - PROCESSED;
try {
PROCESSED += m.read(buffer, PROCESSED, READBUF);
} catch (IOException e) {
}
XPROCESSED = PROCESSED;
}
} catch (IOException e1) {
// Removed because of sensitive data
}
return decryptData(buffer);
}
在Java客戶端中,當您經歷循環時'PROCESSED'的值是多少?我對此感興趣,因爲我很好奇它爲什麼在讀10,000個字節時結束2048個字節。我希望它有1808年閱讀上次通過循環,因爲它在每次迭代中讀取2048字節。 – Poosh
@Poosh 10,000字節是一個例子。我現在不在我的個人電腦上,所以我只能給你估計的價值,我稍後會再次評論準確的價值。 PROCESSED值總是增加1440或2048,最後只增加700。那時候還有2048個字節需要讀取,但正如所說的那樣,它們不會到達客戶端。 – detus
更新:這裏有一些日誌: 工作下載:https://pastebin.com/hFd5TvrF 未能下載:https://pastebin.com/Q3zFWRLB – detus