【问题标题】:Sending and receiving files on socket在套接字上发送和接收文件
【发布时间】:2014-07-31 18:44:19
【问题描述】:

我正在从 java 服务器向远程 Android 客户端发送文件。我使用输出流写入字节。在读取这些字节时,read() 方法会在流结束后继续尝试读取字节。如果我在服务器端关闭outputstream,读取操作工作正常。但是我必须再次在同一个套接字上写入文件所以无法关闭输出流任何解决方案?

注意:我的代码适用于共享单个文件

编写文件的代码

public static void writefile(String IP, String filepath, int port, OutputStream out) throws IOException {
    ByteFileConversion bfc = new ByteFileConversion();
    byte[] file = bfc.FileToByteConversion(filepath);

    out.write(file, 0, file.length);
    out.close(); // i donot want to close this and how can I tell reading side that stream is ended.
    System.out.println("WRITTEN");
}

这是我在 Android 上阅读的文件:

public Bitmap fileReceived(InputStream is) {

    Bitmap bitmap = null;
    String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
    String fileName = "a.png";
    String imageInSD = baseDir + File.separator + fileName;
    //  System.out.println(imageInSD);
    if (is != null) {
        FileOutputStream fos = null;
        OutputStream bos = null;
        try {

            bos = new FileOutputStream(imageInSD);

            byte[] aByte = new byte[1024];
            int bytesRead;
            int index = 0;
            DataInputStream dis = new DataInputStream(is);


            while ((bytesRead = is.read(aByte)) > 0) {
                index = bytesRead + index;
                bos.write(aByte, 0, bytesRead);

                //  index = index+ bytesRead;

                System.out.println("Loop" + aByte + "    byte read are " + bytesRead + "whree  index =" + index);

            }
            bos.flush();
            bos.close();

            Log.i("IMSERVICE", "out of loop");
            java.io.FileInputStream in = new FileInputStream(imageInSD);
            bitmap = BitmapFactory.decodeStream(in);
            bitmap = BitmapFactory.decodeFile(imageInSD);

            Log.i("IMSERVICE", "saved");
            //  if (bitmap != null) 
            //       System.out.println("bitmap is    "+ bitmap.toString());

        } catch (IOException ex) {
            // Do exception handling      
            //      Log.i("IMSERVICE", "exception ");
            System.out.println("ex");
        }
    }

    return bitmap;
}

其实我想重置socket连接

提前致谢

【问题讨论】:

  • 我的代码正确读写文件。我想再次使用即将写入另一个文件的输出流。但是由于输出流很接近所以我不能这样做。如果我不关闭输出流,另一侧的读取操作会卡在继续阅读
  • @RodAlgonquin TCP 无法发送和接收单个数据包。它是一个字节流。您必须添加自己的元数据。
  • @EJP 我明白了,但这并不是他的问题,他希望按照我在下面的建议打开他的输出,但我不知道他们为什么不赞成。
  • @Rod_Algonquin 这正是他的问题。他需要在第一个文件结束后停止阅读,目前除了套接字的流结束之外,他没有办法告诉文件结束。请参阅我的答案 fpr 解决方案。仅仅将阻塞行为移动到一个单独的线程中根本无法解决问题。

标签: java android sockets network-programming


【解决方案1】:

你需要:

  1. 在文件之前发送文件的长度。您可以为此使用DataOutputStream.writeLong(),并在接收者处使用DataInputStream.readLong()
  2. 在接收端从流中准确读取那么多字节:

    while (total < length && (count = in.read(buffer, 0, length-total > buffer.length ? buffer.length : (int)(length-total))) > 0)
    {
        out.write(buffer, 0, count);
        total += count;
    }
    

电子与工程

其实我是想重置socket连接

其实你不想做任何这样的事情。

【讨论】:

  • 我使用了 DataOutputStream.writelong()
【解决方案2】:

如果我不关闭输出流,另一边的读取操作会卡在继续阅读

那是因为客户端套接字的InputStream 仍在等待服务器发送一些数据包从而阻塞了你的主线程。

解决方案:

你可以把你的每一个发送(OutputStream)和读取(InputStream)的数据包从套接字放到一个线程中,以防止在读取和发送时阻塞你的主线程。

创建一个读取InputStream 的线程和另一个读取OutputStream 的线程

旁注:

不要尝试关闭您的 outputStream ,因为它无法再次重新打开,因为文档说:

关闭返回的 OutputStream 将关闭关联的套接字。

close 的一般约定是关闭输出流。关闭的流无法执行输出操作,也无法重新打开。

【讨论】:

  • 我将输出流放在线程中,但结果是一样的。关闭线程中的输出流关闭套接字:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 2016-12-08
  • 1970-01-01
  • 2016-02-21
  • 2013-04-01
  • 2020-12-21
相关资源
最近更新 更多