簡體   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