ServerSocket文件传输丢失字节

时间:2011-07-28 00:23:06

标签: java sockets 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字节的信息。也许我在这里走错了方向?

2 个答案:

答案 0 :(得分:1)

您似乎保留了两个引用相同内容的单独流/读者:this.data_inthis.in。从任一个读取将推进流,然后从另一个读取将看起来“错过”在另一个中读取的数据。此外,您使用DataInputStream方法就像常规旧的InputStream一样使用read(byte[])。 DataInputStream是具有特定用途的专用流。

答案 1 :(得分:1)

对我而言,BufferedReader似乎是问题所在 - 根据http://ulibgcj.sourceforge.net/javadoc/java/io/BufferedReader.html,默认缓冲区大小为8192 ...无论您的默认缓冲区大小是什么,{{1} }将以默认缓冲区大小的步长前进BufferedReader ...因此,即使您不使用它们,data_in通常位于您在身份验证期间消耗的最后一个字节之外的位置。