【发布时间】:2014-03-30 16:16:03
【问题描述】:
我正在尝试将文件从 PC 下载到 Android 设备(模拟器或物理设备)
中小型文件一切正常,但是当我尝试发送大于 10Mb 的文件时,服务器永远不会到达此语句 out2.println("ready");,因此客户端挂起等待来自服务器的 "ready"
似乎服务器卡在这个:os.write(bytearray, 0, bytearray.length);
到目前为止,我已经在模拟器上尝试过了,我将很快报告真实设备上的结果
这是我的客户端部分,在 Android 应用程序中:Android 客户端向服务器发送“下载”字符串,然后从服务器接收“就绪”回复,并开始从 InputStream 读取文件
int filesize = 2022386;
int bytesRead;
int currentTot = 0;
Socket socket1 = new Socket("172.16.6.119", 50001); //data line
Socket socket2 = new Socket("172.16.6.119", 50001); //control line
BufferedReader in2 = new BufferedReader(new InputStreamReader(socket2.getInputStream()));
PrintWriter out2 = new PrintWriter(socket2.getOutputStream(), true);
out2.println("download:"); //control line
String usrtxt = in2.readLine();
if(usrtxt.substring(0,5).equals("ready")) //control line
{
byte [] bytearray = new byte [filesize];
InputStream is = socket1.getInputStream(); //data line
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().toString() + "/sunset.jpg");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(bytearray,0,bytearray.length);
currentTot = bytesRead;
Log.e("DOWNLOAD", "init value: bytesread = " + Integer.toString(bytesRead));
do {
bytesRead =
is.read(bytearray, currentTot, (bytearray.length-currentTot)); //<--does not pull data (WHY?)
Log.e("DOWNLOAD", "bytesread = " + Integer.toString(bytesRead));
if(bytesRead >= 0) currentTot += bytesRead;
} while(bytesRead > -1);
out1.println("finished:");
bos.write(bytearray, 0 , currentTot);
Log.e("DOWNLOAD", Integer.toString(currentTot));
bos.flush();
bos.close();
socket1.close(); socket2.close();
}
这是我的服务器代码:它接受来自客户端的连接,然后从客户端接收“下载”字符串,回复“就绪”,然后将文件放入 OutputStream
while (true) {
final Socket socket = serverSocket.accept(); //data line
final Socket socket2= serverSocket.accept(); //control line
BufferedReader in2 = new BufferedReader(new InputStreamReader(socket2.getInputStream()));
PrintWriter out2 = new PrintWriter(socket2.getOutputStream(), true);
String usrtxt = in2.readLine(); //control line
if(usrtxt.substring(0,8).equals("download"))
{
System.out.println("accepted download request. sending file");
File transferFile = new File("sunset.jpg");
byte[] bytearray = new byte[(int)transferFile.length()];
FileInputStream fin = new FileInputStream(transferFile);
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(bytearray, 0, bytearray.length);
OutputStream os = socket.getOutputStream();
os.write(bytearray, 0, bytearray.length); //data line
os.flush();
os.close();
out2.println("ready"); //control line
socket.close(); socket2.close();
bin.close(); fin.close();
System.out.println("file transfer complete");
}//end if
}//end while
【问题讨论】:
-
您正在从套接字中读取一次,并期望它一次读取全部内容。这是极不可能的。
read仅读取已传输且当前可用的任何数据。 -
@BrianRoach 但我正在使用一个循环,该循环读取直到没有任何东西可以获取。
-
只有当服务器关闭连接时它才会知道“没有什么可以获取”——直到客户端说它已经完成它才会这样做。僵局!阅读marcgravell.blogspot.co.uk/2013/02/…
-
@JonSkeet 但服务器如何知道何时关闭?
-
您的循环包括接受连接。它为每个与其建立的 TCP 连接只循环一次,然后在
socket超出范围时将该连接转储到循环底部。
标签: java android sockets download inputstream