开发者

Socket transferring a file

I have a Java server class like this:

ServerSocket servsock = new ServerSocket(63456);
boolean read = false;
while (!read) {
    Socket sock = servsock.accept();
    int length = 1024;
    byte[] myb开发者_运维技巧ytearray = 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;
}

` And the client is like this:

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();

One question is: Why the loop does not stop at the end of the file? A second question would be, why is also so slow?


It does not stop because

if (i == 1) {

in your server source should be

if (i == -1) {

Or, if you want to be really safe:

if (i <= 0) {

Also, you risk data corruption with this line:

os.write(mybytearray, 0, mybytearray.length);

You should change this to:

os.write(mybytearray, 0, i);

On performance -- move the os.flush(); call to outside the while loop. When you flush a network stream, you are forcing it to dispatch any buffered data to the network. This is forcing the network layer to send and acknowledge 1024-byte TCP payloads (larger Ethernet payloads, of course) which is probably significantly smaller than your PMTU. You only need to flush when you are done sending data, or when you want the client to receive the buffered data now. Removing the flush call from each iteration will allow the OS-level network buffer to do its job, and segment the data into as few packets as possible.


Second question - your client reads bytes directly from the raw socket stream. Use the BufferedInputStream/BufferedOutputStream decorators, this should increase performance:

Server Side

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

Client side

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

The raw streams are not buffered (AFAIK) so you have to add the buffering manually, if needed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜