2010-12-08 65 views
1

我有一个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(); 

的一个问题是:为什么循环不会在停止文件的结尾? 第二个问题是,为什么也这么慢?

回答

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小得多。您只需在发送数据完成后或当您希望客户端接收缓冲数据(现在为)时进行刷新。从每次迭代中删除刷新调用将允许OS级网络缓冲区完成其工作,并将数据分割成尽可能少的数据包。

+0

谢谢,它工作! – hephestos 2010-12-08 08:16:06

2

第二个问题 - 您的客户端直接从原始套接字流中读取字节。使用的BufferedInputStream /的BufferedOutputStream装饰,这应该提高性能:

服务器端

BufferedOutputStream os = new BufferedOutputStream(sock.getOutputStream()); 

客户端

BufferedInputStream is = new BufferedInputStream(sock.getInputStream()); 

原始流没有被缓冲(据我所知),所以你有如果需要,手动添加缓冲。

+0

是的,这增加了一些速度。这很简单;-)我应该亲眼看到它,无论如何,谢谢。 – hephestos 2010-12-08 08:17:44