【问题标题】:how to reopen a closed socket in order to send message back to the client如何重新打开关闭的套接字以便将消息发送回客户端
【发布时间】:2013-09-24 15:04:02
【问题描述】:

使用 DataInputStream 获取从 Android 客户端发送到此 Java 桌面服务器的 int 和 long。之后,从 Android 客户端收到一个 pdf 文件。客户端向服务器发送的总共3个文件。问题是在另一个方向发送时。

我必须在 while 循环之后立即关闭输入和输出流。如果我不这样做,pdf文件将被损坏,程序将停止并卡在while循环中,并且不会继续执行到线程结束。

如果我必须关闭输入和输出流,则套接字将关闭。如何重新打开同一个套接字?

我需要重新打开同一个套接字,因为需要向 Android 客户端发送一条消息,表明服务器从中收到了 pdf 文件,以向它发送确认文件已被服务器安全接收。

有多个 Android 客户端连接到同一个 Java 服务器,所以我想需要相同的套接字才能将消息发送回客户端。如果没有套接字,将很难确定将消息发送到哪个客户端。

       byte[] buffer = new byte[fileSizeFromClient];

        while((count = dis.read(buffer)) > 0){
            bos.write(buffer, 0, count);
        }

       dis.close();  // closes DataInputStream dis
       bos.close();  // closes BufferedOutputStream bos

编辑:

来自客户端的代码

   dos.writeInt((int)length); // sends the length as number bytes is file size to the server
   dos.writeLong(serial); // sends the serial number to the server

                int count = 0; // number of bytes

                while ((count = bis.read(bytes)) > 0) {
                    dos.write(bytes, 0, count);
                }

     dos.close(); // need to close outputstream or result is incomplete file sent to server
                  // and the server hangs, stuck on the while loop
                  // if dos is closed then the server sends error free file

【问题讨论】:

    标签: java android sockets networking tcp


    【解决方案1】:

    没有。您无法重新打开套接字。你必须做一个新的。完成文件传输后,您不必关闭套接字。服务器仍然可以重复使用它来发送您的消息回复。由于您已经发送了文件大小,您的服务器可以使用它来了解您的客户端何时完成发送完整文件。之后,您的服务器可以将您的回复发送给客户端。

    在你当前的循环中试试这个。

     int bytesRead = 0;
     while((count = dis.read(buffer)) > 0 && bytesRead != fileSizeFromClient){
      bytesRead += count; 
      bos.write(buffer, 0, count);
     }
     bos.close();
     //don't close the input stream
    

    【讨论】:

    • 我尝试了这段代码,但由于某种原因,每次文件到达时都不完整。小于实际尺寸。
    • @Kevik 你如何将文件大小发送到服务器?你客户的代码是什么?
    • 文件大小是从客户端发送的,在服务器上接收没有问题,如果我不关闭外流(这也会关闭服务器),并在服务器上使用 System.out.println 进行验证) 这将导致接收到的 pdf 文件不完整和损坏,并且在循环时会卡在服务器端的死锁中
    • 此代码不正确。它过于频繁地迭代一次,并且很可能在最后一次正确的迭代中读取太多字节。您需要反转测试;为 'count != 0' 添加一个测试;并使用 (int)Math.min(buffer.length, fileSizeFromClient-bytesRead) 作为 read() 方法的长度参数。
    猜你喜欢
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-14
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    相关资源
    最近更新 更多