繁体   English   中英

加快我的Java TCP传输速度!

[英]Speed up my Java tcp transfer!

我需要加快千兆以太网连接之间的传输速度。 现在,我正在做几乎完全像这样的事情,但是当我在下面运行此代码时,我只看到其中的40%。

在测试之前,我还在所有(Mac Pro)计算机上运行了此脚本

#!/bin/bash

sudo sysctl -w net.inet.tcp.win_scale_factor=8
sudo sysctl -w kern.ipc.maxsockbuf=16777216
sudo sysctl -w net.inet.tcp.sendspace=8388608
sudo sysctl -w net.inet.tcp.recvspace=8388608

实际代码如下:

import java.io.*;
import java.nio.*;
import java.net.*;

public class BandwidthTester {
private static final int OUT_BUF = (1 << 17),
                    IN_BUF = (1 << 17), SEND_BUF = (1 << 22), RECV_BUF = (1 << 22);
public static void main(String[] args) {
    try {
        // server
        if (args.length == 0) {
            ServerSocket sock = new ServerSocket();
            sock.bind(new InetSocketAddress(41887));

            // wait for connection
            Socket s = sock.accept();

            s.setSendBufferSize(SEND_BUF);

            System.out.println("Buffers: " + s.getSendBufferSize() + " and " + s.getReceiveBufferSize());

            sock.close();

            BufferedOutputStream bOut = new BufferedOutputStream(s.getOutputStream(), OUT_BUF);

            // send lots of data
            sendLotsOfData(bOut);
        } else if (args.length == 2) {
            String host = args[0];
            int port = Integer.parseInt(args[1]);

            System.out.println("Connecting to " + args[0] + ":" + args[1]);

            Socket sock = new Socket();
            sock.setReceiveBufferSize(RECV_BUF);
            sock.connect(new InetSocketAddress(host, port));

            System.out.println("Buffers: " + sock.getSendBufferSize() + " and " + sock.getReceiveBufferSize());

            BufferedInputStream bIn = new BufferedInputStream(sock.getInputStream(), IN_BUF);
            getLotsOfData(bIn);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}


public static void getLotsOfData(InputStream in) {
    System.out.println("Getting data...");
    try {
        long start = System.currentTimeMillis();

        ByteBuffer intConv = ByteBuffer.allocate(4);

        in.read(intConv.array());
        int len = intConv.getInt(0);
        for (int i=0; i < len; i++) {
            in.read(intConv.array());
            int val = intConv.getInt(0);
        }

        long end = System.currentTimeMillis();

        double elapsed = ((double)(end - start)) / (1000.0);

        System.out.println("Read in " + elapsed + " seconds: " + ( (4.0*8.0*len/elapsed) + " bits per second"));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void sendLotsOfData(OutputStream out) {
    System.out.println("Sending data...");
    try {
        long start = System.currentTimeMillis();

        int len = (1 << 29);

        ByteBuffer intConv = ByteBuffer.allocate(4);
        intConv.putInt(0, len);
        out.write(intConv.array());
        for (int i=0; i < len; i++) {
            intConv.putInt(0, i);
            out.write(intConv.array());
        }

        out.flush();

        long end = System.currentTimeMillis();

        double elapsed = ((double)(end - start)) / (1000.0);

        System.out.println("Sent in " + elapsed + " seconds: " + ( (4.0*8.0*len/elapsed) + " bits per second"));
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}
}

有什么建议么? 发送所有这些数据大约需要42秒钟,但即使在此处提高10%,也会对我的程序产生巨大影响。

您可以尝试的一件事是为ByteBuffer使用更大的缓冲区。 从4字节变为16,我从12秒的传输时间变为9秒的传输时间。 (使用2 ^ 26而不是2 ^ 29进行测试)

也就是说,它正在本地运行; 因此,应该不会遇到实际的网络问题。

用于发送的一些脏修改代码:

ByteBuffer intConv = ByteBuffer.allocate(16);
intConv.putInt(0, len);
out.write(intConv.array(),0,4);
for (int i=0; i < len; i+=4) {
    for(int j=0; j<4; j++)
        intConv.putInt(4*j, i);
    out.write(intConv.array());
}

和接收:

ByteBuffer intConv = ByteBuffer.allocate(16);
in.read(intConv.array(),0,4);
int len = intConv.getInt(0);
for (int i=0; i < len; i+=4) {
    in.read(intConv.array());
    for(int j=0; j<4; j++)
    {
      int val=intConv.getInt(j*4);
    }
}

显然,接收端将需要进行一些修改以处理奇怪的情况,例如“如果流中仅剩余3个int /从流中读取数据,将会怎样?”,但我认为这足以查看它是否可以提高性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM