ServerSocket 文件传输丢失字节
问题
我已经通过数据包嗅探器确认来自客户端的所有数据都已完全发送,并且服务器接收的数据也完整,但是存在一个小问题。
这是服务器内客户端线程相关部分的基本表示。
this.data_in = new DataInputStream(sock.getInputStream());
this.in = new InputStreamReader(this.data_in);
服务器将使用 BufferedReader 读取身份验证数据,一旦身份验证完成,它将从套接字读取数据,如下所示。变量“fos”是 DataInputStream 数据正在写入的 FileOutputStream。
int read = 0;
byte[] buffer = new byte[8192];
while((read = data_in.read(buffer)) != -1) {
fos.write(buffer, 0, read);
bytes_received += read;
}
这一切在概念上似乎都是正确的,但实际上,读入的文件的前 1450 个字节丢失了。我尝试使用新的 DataInputStream(sock.getInputStream()) 以防流中的位置很奇怪,但仍然没有运气。感谢您的帮助!
更新 1
因此,我可以使用 BufferedReader 功能,我创建了一种方法来读取字符串行,就像我之前使用它们一样。请参阅下面的代码。
int input;
boolean run = true;
while((input = in.read()) != -1 && run) {
run = true;
char[] chars = Character.toChars(input);
for(char c : chars) {
if(c == '\n') {
run = false;
break;
} else if(c != '\r') {
sb.append(c);
}
}
}
尽管解决方案看起来很棒,但仍然缺少 1450 字节的信息。也许我在这里走错了方向?
Issue
I have confirmed via a packet sniffer that all data coming from the client is being totally sent, and that the data being received by the server is complete as well, however there is a slight problem.
Here is a basic representation of relevant parts of the client thread within the server.
this.data_in = new DataInputStream(sock.getInputStream());
this.in = new InputStreamReader(this.data_in);
The server will read in authentication data using the BufferedReader, and once authentication is complete it will read data from the socket, like so. The variable 'fos' is a FileOutputStream that the DataInputStream data is being written to.
int read = 0;
byte[] buffer = new byte[8192];
while((read = data_in.read(buffer)) != -1) {
fos.write(buffer, 0, read);
bytes_received += read;
}
This all seems correct in concept, however, in practice the first 1450 bytes of the file read in are missing. I have tried using a new DataInputStream(sock.getInputStream()) in case the position in the stream was weird but still no luck. Thanks for any help!
Update 1
So I could use BufferedReader functionality I made a method to read in string lines as I was using them before. See below code.
int input;
boolean run = true;
while((input = in.read()) != -1 && run) {
run = true;
char[] chars = Character.toChars(input);
for(char c : chars) {
if(c == '\n') {
run = false;
break;
} else if(c != '\r') {
sb.append(c);
}
}
}
As great of a solution it seemed, there is still 1450 bytes of information missing. Maybe I'm going in the wrong direction here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在我看来,
BufferedReader
是问题所在 - 根据 http://ulibgcj.sourceforge.net/javadoc/java/io/BufferedReader.html 的默认缓冲区大小为 8192...无论您的情况是多少,该默认缓冲区大小都是BufferedReader
将以默认缓冲区大小为步长推进data_in
...因此,即使您不使用它们,data_in
通常也会在超出您在身份验证期间消耗的最后一个字节的位置。To me it looks like the
BufferedReader
is the problem - according to http://ulibgcj.sourceforge.net/javadoc/java/io/BufferedReader.html is has default buffer size of 8192... whatever this default buffer size is in your case, theBufferedReader
will advance thedata_in
in steps of that default buffer size... so even if you don't consume themdata_in
is usually on a position beyond the last bytes you consumed during authentication.您似乎保留了两个引用同一事物的独立流/读取器:
this.data_in
和this.in
。从其中任何一个读取都会推进流,然后从另一个读取将出现“错过”在另一个中读取的数据。另外,您正在使用 DataInputStream像常规的旧InputStream一样,使用 read(byte[]) 方法。 DataInputStream 是具有特定用途的专用流。You seem to be keeping two separate stream/readers that refer to the same thing:
this.data_in
andthis.in
. Reading from either will advance the stream, and then reads from the other will appear to "miss" the data that was read in the other. Also, you're using the DataInputStream just like a regular old InputStream by using the read(byte[]) method. DataInputStream is a specialized stream with a specific purpose.