我使用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