套接字DataInputStream和EOF标志:是否存在"冲突"在istream.write之后用istream.writeUTF写的时候?

时间:2018-04-07 12:37:41

标签: java sockets datainputstream dataoutputstream

我正在编写一个程序来在两台计算机之间传输文件,但我没有关闭套接字,因为我使用相同的套接字来传输其他邮件(例如传输服务器&文件夹组织)。

在某个时刻,我有这个代码将文件从服务器传输到客户端:

服务器

  System.out.println("Sending " + threadItem.second.getName() + " of " + threadItem.second.length() + "b");

  FileInputStream fileInputStream = new FileInputStream(threadItem.second);

  byte[] buffer = new byte[BLOCK_SIZE];

  int count;
  while ((count = fileInputStream.read(buffer)) > 0) {
      outputStream.write(buffer, 0, count);
  }

  outputStream.write(END_OF_STREAM, 0, 1);

  System.out.println("File sent.");

  fileInputStream.close();

客户端收到:

  FileOutputStream fOutputStream = new FileOutputStream(new File("./received/" + obj.toString()));
  byte[] buffer = new byte[4096];
  int count;

  while ((count = dataInputStream.read(buffer)) > 0 && !(buffer[count - 1] == '\0')) {
      fOutputStream.write(buffer, 0, count);
  }

  fOutputStream.close();

它有效,但真正的问题是在上述情况之后我从服务器向客户端发送另一条消息:

服务器

outputStream.writeUT(new JSONObject()
    .put("command", MessageHandler.ConnectionMessage.OVER.toString())
                                                        .toString());

客户端使用:

接收
JSONObject jsonObject = new JSONObject(dataInputStream.readUTF());

但是,在上面的这一行我得到:

SEVERE: null
java.io.UTFDataFormatException: malformed input around byte 1
    at java.io.DataInputStream.readUTF(DataInputStream.java:656)
    at java.io.DataInputStream.readUTF(DataInputStream.java:564)
    at labrpc.secondquestion.Client.lambda$jButton3ActionPerformed$1(Client.java:499)
    at java.lang.Thread.run(Thread.java:748)

某种程度上write损坏了writeUTF或类似内容(我一直在搜索与其相关的所有内容,但没有发现任何相关内容),我已尝试删除write 1}}从服务器到测试并且这些错误没有出现,但它是一个重要的例程。

我的问题是:在套接字通信中,write和writeUTF是否互斥?

提前致谢。

1 个答案:

答案 0 :(得分:1)

我按照JB Nizet

的提示解决了这个问题

由于我已经拥有文件的长度,我发现我可以将长度发送给客户端,因此它只能迭代指定的长度,按长度推断文件的虚拟结尾已读取字节。

服务器端:      FileInputStream fileInputStream = new FileInputStream(threadItem.second);

 progressListener.dmaSend(threadItem.second.getName(), length);

 byte[] buffer = new byte[BLOCK_SIZE];

 for (int curLength, accumulator = 0; accumulator < length; outputStream.write(buffer, 0, curLength)) {
     System.out.println("Reading part [" + accumulator + "," + length + "]");
     accumulator += (curLength = fileInputStream.read(buffer));
     System.out.println("Sending part [" + accumulator + "," + length + "]");
 }

 System.out.println("File sent.");

客户端:

 FileOutputStream fOutputStream = new FileOutputStream(new File("./received/" + obj.toString()));
 byte[] buffer = new byte[BLOCK_SIZE];

 for (int curLength, accumulator = 0; accumulator < length; fOutputStream.write(buffer, 0, curLength)) {
     System.out.println("Reading part [" + accumulator + "," + length + "]");
     accumulator += (curLength = dataInputStream.read(buffer));
     System.out.println("Sending part [" + accumulator + "," + length + "]");
 }

 fOutputStream.close();

因此,可以在服务器上编写(套接字输出)/读取(文件输入)并在客户端上写入(文件输出)/读取(套接字输入)。