简体   繁体   English

套接字文件传输:接收器卡在缓冲区/写入存储区中

[英]Socket file transfer: Receiver stuck in reading from buffer/writing to storage

static void sendFile(Socket socket, File file) throws IOException {

    File testFile = new File( Environment.getExternalStorageDirectory().toString()+"/DCIM/Camera/Test.jpg");
    byte [] buffer = new byte[(int)testFile.length()];
    FileInputStream fis = new FileInputStream(testFile);
    BufferedInputStream bis = new BufferedInputStream(fis);
    Log.d(DebugTag, "Trying to read testFile from storage into buffer");
    bis.read(buffer,0,buffer.length); 
    Log.d(DebugTag, "Read testFile into buffer");
    OutputStream os = socket.getOutputStream();
    Log.d(DebugTag, "Trying to write testFile from buffer into output stream");
    os.write(buffer, 0, buffer.length);
    Log.d(DebugTag, "Wrote testFile from buffer into output stream");
    os.flush();
    Log.d(DebugTag, "Outputstream flushed");
}

static void receiveFile(Socket socket) throws IOException {

    InputStream is = socket.getInputStream();
    String receivedFileDirectory = Environment.getExternalStorageDirectory().toString()+"/Pictures/receivedFile.jpg";
    File receivedFile = new File(receivedFileDirectory);
    //check if directory exists, otherwise create it
    if (receivedFile.exists()) {
        Log.d(DebugTag, "Filename at destination already exists");
    } else if (!receivedFile.exists()) {
        Log.d(DebugTag, "Filename at destination does not exist, trying to create it!");
        receivedFile.createNewFile();
        Log.d(DebugTag, "Created file!");
    }

    Log.d(DebugTag, "Preparing file reception. Destination:"+receivedFileDirectory);
    OutputStream os = new FileOutputStream(receivedFileDirectory);
    Log.d(DebugTag, "established outputstream to file directory");
    byte[] buffer = new byte[2048];
    int length;
    Log.d(DebugTag, "Trying to read inputstream into buffer and write file to destination");
    while ((length = is.read(buffer)) >0 ) {
        os.write(buffer,0,length);
    }
    Log.d(DebugTag, "File received.");
    os.flush();
    os.close();
    is.close();
    Log.d(DebugTag, "Closed in and out streams");

}

The sender file seems to work perfectly, I get every log message till "outputstream flushed". 发件人文件似乎工作得很好,我得到每条日志消息,直到“outputstream刷新”。 On the receiver side, everything seems to go well until the code reaches the while loop: The last log msg I get is always "Trying to read inputstream into buffer and write file to destination", but not "File received" and the following messages. 在接收器方面,一切似乎都顺利,直到代码到达while循环:我得到的最后一个日志msg始终是“尝试将输入流读入缓冲区并将文件写入目标”,但不是“文件已接收”以及以下消息。 Weird thing is: I receive the test file and can open it (though it takes some seconds - don't know if this is typical for android). 奇怪的是:我收到测试文件并可以打开它(虽然它需要几秒钟 - 不知道这是否是Android的典型)。 Any clues why the code gets stuck in the while loop? 代码在while循环中陷入困境的任何线索?

Second question: This is my first Android/Java app. 第二个问题:这是我的第一个Android / Java应用程序。 Is this code alright for sending and receiving files over sockets? 这个代码可以通过套接字发送和接收文件吗? Even if files get bigger (up to >100MB)? 即使文件变大(最大> 100MB)?

Thanks in advance! 提前致谢!

That is.read(buffer) will only return zero if the other side of the connection is gracefully closed (or throw an exception on errors), so what you are missing is the socket.close() on the sending side. 如果连接的另一端正常关闭(或者在错误上抛出异常),则is.read(buffer)将仅返回零,因此您缺少的是发送方的socket.close()

os.flush() is not enough here since TCP does not know when you are done sending data. os.flush()在这里还不够,因为TCP不知道你什么时候发送数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM