电脑上socket的速度是120MB/s,正常吗?

发布于 2024-12-11 18:00:32 字数 1763 浏览 0 评论 0原文

我在一台计算机上测试了通过socket从一个程序向另一个程序传输数据的性能,速度为120MBytes/s,正常吗?

我的服务器和客户端程序都非常简单。

我的电脑是AMD Athlon X2 4000+,4G DDR2 667 RAM,Windows XP SP3。

我朋友说速度慢,应该更快。但我不知道如何改进它们,或者是否有其他库可以尝试获得更好的速度?

更新

服务器和客户端程序都在我自己的计算机上,一台计算机网卡会不会限速?


服务器.java

import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(6666);
        Socket socket = server.accept();
        OutputStream output = socket.getOutputStream();

        byte[] bytes = new byte[10 * 1024]; // 10K
        for (int i = 0; i < bytes.length; i++) { bytes[i] = 12; } // fill the bytes

        // send them again and again
        while (true) {
            output.write(bytes);
        }
    }
}

客户端.java

public class SimpleClient {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 6666);
        InputStream input = socket.getInputStream();
        long total = 0;
        long start = System.currentTimeMillis();

        byte[] bytes = new byte[10240]; // 10K

        // read the data again and again
        while (true) {
            int read = input.read(bytes);
            total += read;
            long cost = System.currentTimeMillis() - start;
            if (cost > 0 && System.currentTimeMillis() % 1000 == 0) {
                 System.out.println("Read " + total + " bytes, speed: " + (total / (1024.0*1024)) / (cost / 1000.0) + " MB/s");
            }
        }
    }

}

I tested the performance of transferring data from a program to another over socket on a single computer, and the speed is 120MBytes/s, is it normal?

My server and client programs are both extremely simple.

And my computer is AMD Athlon X2 4000+, 4G DDR2 667 ram, with windows xp sp3.

My friend said it was slow, and should be faster. But I don't know how can I improve them, or is there any other libraries I can try to get a better speed?

UPDATE

The server and client programs were both on my own computer, a single computer. The network card will limit the speed or not?


Server.java

import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(6666);
        Socket socket = server.accept();
        OutputStream output = socket.getOutputStream();

        byte[] bytes = new byte[10 * 1024]; // 10K
        for (int i = 0; i < bytes.length; i++) { bytes[i] = 12; } // fill the bytes

        // send them again and again
        while (true) {
            output.write(bytes);
        }
    }
}

Client.java

public class SimpleClient {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 6666);
        InputStream input = socket.getInputStream();
        long total = 0;
        long start = System.currentTimeMillis();

        byte[] bytes = new byte[10240]; // 10K

        // read the data again and again
        while (true) {
            int read = input.read(bytes);
            total += read;
            long cost = System.currentTimeMillis() - start;
            if (cost > 0 && System.currentTimeMillis() % 1000 == 0) {
                 System.out.println("Read " + total + " bytes, speed: " + (total / (1024.0*1024)) / (cost / 1000.0) + " MB/s");
            }
        }
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

围归者 2024-12-18 18:00:32

你能给我这个程序的输出吗?

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(6666);
        Socket socket = server.accept();
        OutputStream output = socket.getOutputStream();

        byte[] bytes = new byte[32*1024]; // 32K
        while (true) {
            output.write(bytes);
        }
    }
}
public class SimpleClient {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 6666);
        InputStream input = socket.getInputStream();
        long total = 0;
        long start = System.currentTimeMillis();

        byte[] bytes = new byte[32*1024]; // 32K
        for(int i=1;;i++) {
            int read = input.read(bytes);
            if (read < 0) break;
            total += read;
            if (i % 500000 == 0) {
                long cost = System.currentTimeMillis() - start;
                System.out.printf("Read %,d bytes, speed: %,d MB/s%n", total, total/cost/1000);
            }
        }
    }
}

在我的机器上打印

Read 25,586,204,672 bytes, speed: 5,245 MB/s
Read 53,219,426,304 bytes, speed: 5,317 MB/s
Read 85,018,968,064 bytes, speed: 5,416 MB/s
Read 117,786,968,064 bytes, speed: 5,476 MB/s

尝试多次发送 32K 块(至少 2 秒),您应该获得 400 MB/s 或更多。例如至少10,000次。

在速度非常快的机器上,您可以在单个客户端上获得 1 GB/s 的速度。对于多个客户端,您可能会获得 8 GB/s。

这是一个示例

使文件传输更高效的Java


如果您如果有一块 100 Mb 的卡,您的预期速度约为 11 MB/s(字节每秒)。

同样,对于 1 Gb 以太网,您预计约为 110 MB/s。

对于 10 Gig-E 以太网,您可能会达到 1 GB/s,但除非您的系统经过高度调整,否则您可能只能达到该速度的一半。

Can you give me the output of this program?

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(6666);
        Socket socket = server.accept();
        OutputStream output = socket.getOutputStream();

        byte[] bytes = new byte[32*1024]; // 32K
        while (true) {
            output.write(bytes);
        }
    }
}
public class SimpleClient {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 6666);
        InputStream input = socket.getInputStream();
        long total = 0;
        long start = System.currentTimeMillis();

        byte[] bytes = new byte[32*1024]; // 32K
        for(int i=1;;i++) {
            int read = input.read(bytes);
            if (read < 0) break;
            total += read;
            if (i % 500000 == 0) {
                long cost = System.currentTimeMillis() - start;
                System.out.printf("Read %,d bytes, speed: %,d MB/s%n", total, total/cost/1000);
            }
        }
    }
}

on my machine prints

Read 25,586,204,672 bytes, speed: 5,245 MB/s
Read 53,219,426,304 bytes, speed: 5,317 MB/s
Read 85,018,968,064 bytes, speed: 5,416 MB/s
Read 117,786,968,064 bytes, speed: 5,476 MB/s

Try sending 32K blocks many times (for at least 2 seconds) and you should get 400 MB/s or more. e.g. at least 10,000 times.

On a very fast machine you can get 1 GB/s on a single client. With multiple clients you might get 8 GB/s.

Here is an example

Making file transfer more efficient Java


If you have a 100 Mb card you can expect around 11 MB/s (bytes per second).

Similarly for 1 Gb ethernet youc an expect around 110 MB/s

For a 10 Gig-E ethernet you might get up to 1 GB/s however you might only get half this unles syour system is highly tuned.

走过海棠暮 2024-12-18 18:00:32

您只需传输 10k 字节即可执行测试。您正在做的很多事情都会产生开销,而如此小的数据集可能会因这种开销而产生偏差。 (例如创建套接字、分配内存等)您应该创建并传输更大的数据集(数十MB+),以便更现实地了解正在发生的情况。这样做将使开销成为数据传输过程中较小、不太重要的部分。

您还应该多次执行此测试(> 10)并取平均值,因为您的计算机将在不同的随机时间点承受来自服务、网络传输等的负载,并且这些负载将影响您的传输速率。通过 10 次以上的迭代,您还可以删除任何异常缓慢的运行时间,例如 > 2 个标准差。

You're only transferring 10k bytes to perform your test. There is overhead to a lot of what you're doing and such a small set of data may be getting skewed by this overhead. (e.g. creating sockets, allocating memory etc.) You should create and transfer a much larger set of data (dozens of MBs+) to get a more realistic idea of what's going on. Doing this will make the overhead a smaller, less significant part of the data transfer process.

You should also perform this test a number of times (> 10) and take the average because your computer will be under loads from services, network transfers etc. at different, random points in time and these loads will affect your transfer rate. With 10+ iterations you could also drop any run times that are unusually slow, such as > 2 standard deviations.

野却迷人 2024-12-18 18:00:32

网卡会不会限速?

您正在使用 127.0.0.1 - 本地/环回地址。来自/到该地址的流量不通过网卡。

这意味着这不是衡量真实网络吞吐量的有效方法。然而,它是 Java 在您的计算机上通过本地网络堆栈移动数据的能力的合理衡量标准。


有趣的是,将您获得的结果与用 C 或 C++ 编写的等效客户端/服务器对进行比较。

The network card will limit the speed or not?

You are using 127.0.0.1 - the local / loopback address. Traffic from / to that address doesn't pass through the network card.

This means that this is not a valid way to measure real network throughput. However, it is a reasonable measure of Java's ability to move data through the local network stack ... on your machine.


What would be interesting would be to compare the result you are getting with an equivalent client / server pair written in C or C++.

柠檬色的秋千 2024-12-18 18:00:32

测试同一主机中两个对等点之间的带宽根本不会使用 NIC 或网络,而是全部环回。因此你的数据基本上没有意义。在两台计算机之间尝试一下。

Testing bandwidth between two peers in the same host doesn't exercise the NIC or the network at all, it is all looped back. Your data is therefore basically meaningless. Try it between two computers.

听风念你 2024-12-18 18:00:32

WinXP 不支持自动窗口缩放,并且套接字的发送/接收缓冲区大小可能对于吞吐量测试来说太低。

此外,FileInputStream(套接字实际上使用 FileInputStream)在 Windows 上的 char[] 缓冲区比本机代码中的 Linux 更小。读/写是通过堆栈上的辅助缓冲区完成的,并且您放置的大块将被集中通过。

使用大型直接缓冲区(与套接字缓冲区一样大)是提高吞吐量的最佳选择。

WinXP doesn't support auto-window scaling and probably the send/receive buffer size of the socket is too low for throughput test.

More also FileInputStream (socket uses FileInputStream practically) has smaller char[] buffer on Windows than Linux in the native code. The read/write is done via auxiliary buffer on the stack and the large chunk you put is funneled through.

Using a large direct buffer (as large as the socket buffers) is your best bet for throughput.

记忆消瘦 2024-12-18 18:00:32

嗯,这很有趣,但是这个 nio 实现与上面提供的 SimpleServer/SimpleClient 相当(有时实际上击败了它)(尽管这只是在单线程模式下运行,无论如何都是一对一的!!!

) SimpleServer/SimpleClient 以及该目录中提供的 nio IntegTestLocalhostThroughput.java...

https: //github.com/deanhiller/webpieces/tree/master/core/core-asyncserver/src/test/java/org/webpieces/nio/api/throughput

我只是觉得这相当有趣的是,nio 基本上与旧的 io 一样快,但扩展性更好。

Well, it is interesting, but this nio implementation was on par with the SimpleServer/SimpleClient provided above(and sometimes actually beat it) (Though this is only if run in single threaded mode which is more one to one anyways!!!)

Both SimpleServer/SimpleClient and the nio IntegTestLocalhostThroughput.java provided in this directory...

https://github.com/deanhiller/webpieces/tree/master/core/core-asyncserver/src/test/java/org/webpieces/nio/api/throughput

I just thought that was quite interesting that nio is basically just as fast but scales better than the old io stuff.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文