我有一个像这样的Java服务器类:
ServerSocket servsock = new ServerSocket(63456);
boolean read = false;
while (!read) {
Socket sock = servsock.accept();
int length = 1024;
byte[] mybytearray = new byte[length];
OutputStream os = sock.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
while (true) {
int i = bis.read(mybytearray, 0, mybytearray.length);
if (i == 1) {
break;
}
os.write(mybytearray, 0, mybytearray.length);
os.flush();
}
sock.close();
read = true;
}
` 客户端是这样的:
Socket sock = new Socket("127.0.0.1", 63456);
byte[] mybytearray = new byte[1024];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("C:/tmp/NEWtmp.rar");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
while(bytesRead != -1 ) {
bos.write(mybytearray, 0, bytesRead);
bytesRead = is.read(mybytearray, 0, mybytearray.length);
}
bos.close();
sock.close();
一个问题是:为什么循环不会在文件末尾停止? 第二个问题是,为什么这么慢?
答案 0 :(得分:4)
它不会因为
而停止if (i == 1) {
您的服务器源中的应为
if (i == -1) {
或者,如果你想要真正安全:
if (i <= 0) {
此外,您还可以通过此行冒着数据损坏的风险:
os.write(mybytearray, 0, mybytearray.length);
您应该将其更改为:
os.write(mybytearray, 0, i);
关于效果 - 将os.flush();
调用移至while
循环之外。刷新网络流时,强制它将任何缓冲的数据分发到网络。这迫使网络层发送和确认1024字节的TCP有效载荷(当然,更大的以太网有效载荷),这可能远小于您的PMTU。您只需在完成数据发送后刷新,或者希望客户端接收缓冲数据现在。从每次迭代中删除刷新调用将允许操作系统级网络缓冲区完成其工作,并将数据分段为尽可能少的数据包。
答案 1 :(得分:2)
第二个问题 - 您的客户端直接从原始套接字流中读取字节。使用BufferedInputStream / BufferedOutputStream装饰器,这应该可以提高性能:
服务器端
BufferedOutputStream os = new BufferedOutputStream(sock.getOutputStream());
客户端
BufferedInputStream is = new BufferedInputStream(sock.getInputStream());
原始流未缓冲(AFAIK),因此您必须手动添加缓冲(如果需要)。