我可能已经盯着这个太久了,看不出问题是什么。
我有一台接受多个客户端连接并保存套接字的服务器。然后,服务器可以向客户端发送控制消息以执行任务,除其他外,我想将文件发送到所有连接的客户端,但客户端似乎只接收其中的一部分。
出于测试目的,我有一个随机生成的文本文件69075字节但是虽然看起来整个文件都被发送,但客户端只能接收大约57000字节(不同)。我在服务器应用程序上添加了一个按钮,让我关闭客户端套接字,当我这样做时,客户端收到-1,然后是剩下的丢失文件。
服务器发送文件:
try {
getClientList().get(0).setLocked(true);
byte [] mybytearray = new byte [1024];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
OutputStream os = getClientList().get(0).getmSocket().getOutputStream();
Boolean eof = false;
int bytesRead;
int total = 0;
do {
bytesRead = bis.read(mybytearray, 0, mybytearray.length);
if (bytesRead != -1) {
os.write(mybytearray, 0, bytesRead);
total += bytesRead;
Log.d(TAG_SF, "Total: "+total+" :Sent: "+ bytesRead);
} else {
eof = true;
Log.d(TAG_SF, "EOF, Total sent: " + total);
}
} while (!eof);
os.flush();
bis.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
getClientList().get(0).setLocked(false);
}
在发送文件之前,使用文件名和文件大小向客户端发送一条消息,并且收到确认消息。
客户端接收文件:
try {
int total = 0;
byte[] myByteArray = new byte[1024];
int bytesRead;
InputStream is = serverSocket.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(path+SD_DIRECTORY+fileName));
do {
bytesRead = is.read(myByteArray, 0, myByteArray.length);
if (bytesRead != -1){
bos.write(myByteArray, 0, bytesRead);
total = total+bytesRead;
Log.e(TAG,"Total > "+total+ ": No Bytes : "+bytesRead);
} else {
Log.e(TAG,"EOF, total received: "+total);
break;
}
} while (total < fileLength); //fileLength and filename are sent before file
Log.e(TAG,"Total > "+total+ ": No Bytes : "+bytesRead);
bos.flush();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
答案 0 :(得分:0)
问题不在于发送和接收的代码,它工作正常。
我首先向客户端发送一条消息,其中包含指示要发送文件的控制代码,后跟文件大小和文件名。然后客户端等待文件,但服务器在客户端准备好之前就开始发送,并且错过了文件的开头。
要测试,在发送文件名之后和发送文件之前将服务器线程置于休眠状态几秒钟,它可以正常工作。我可能会让客户端向服务器发送“准备好”的消息作为更好的解决方案。
编辑: 虽然这有效,但它不是答案,它似乎与使用缓冲和非缓冲流有关(参见EJP评论)。将做一些重写和相应更新。不确定SO协议,我应该删除错误的答案吗?
编辑(再次) EJP注释绝对正确,它与打开缓冲输入流以接收文件名,然后在其他地方打开无缓冲流以传输文件有关。我的知识在这个领域是有限的(通常),所以我只是写了两个使用相同的无缓冲流。