我在我的应用程序中使用了很多套接字来发送文件,但我仍然没有弄清楚如何确保文件是否已完全通过套接字发送而没有任何问题。
这是我的代码:
socket = new Socket(HOST, 1400);
System.out.println(socket);
System.out.println("Connecting...");
Log.i("Images","in the service"+filepath+"");
Log.i("Images","filepath in the async "+""+filepath+"");
File fil=new File(filepath);
System.out.println(fil);
System.out.println(fil.getName());
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeInt(1);
dos.writeUTF(fil.getName());
int filesize = (int) fil.length();
dos.writeInt(filesize);
byte [] buffer = new byte [filesize];
FileInputStream fis = new FileInputStream(fil.toString());
BufferedInputStream bis = new BufferedInputStream(fis);
//Sending file name and file size to the server
bis.read(buffer, 0, buffer.length); //This line is important
dos.write(buffer, 0, buffer.length);
fis.close();
dos.flush();
//close socket connection
// socket.close();
dos.close();
os.close();
//socket.close();
}
catch(Exception e){
System.out.println("Error::"+e);
//System.out.println(e.getMessage());
//e.printStackTrace();
//Log.i("******* :( ", "UnknownHostException");
}
答案 0 :(得分:0)
让接收方在收到所有数据后向您发送确认。然后你知道所有的数据一直到应用程序。没有别的可以告诉你的。
根据@ greenapp上面的评论,您的代码不正确。你假设read()填充缓冲区。在Java中复制流的规范方法如下:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
这适用于任何非零大小的缓冲区。没有必要分配文件大小的缓冲区。在两端使用它。如果需要读取预先发送的特定长度,则需要跟踪已读取的内容,并确保只读取循环中的那么多字节。所需的修改是微不足道的:
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;
}
E&安培; OE
答案 1 :(得分:-1)
您正在使用TCP套接字,这可确保将发送数据包,或报告错误。在Android上,该错误将是一个IOException,write()或flush()将抛出。为了知道是否发生了错误,这意味着数据传输没有完成,您所要做的就是捕获IOException。
换句话说,无论调用flush()之后发生什么,只有在发送数据完成且没有错误时才会执行。
您可能也希望在服务器上返回响应,因此如果部分数据未完成,它可以向客户端报告。