gpt4 book ai didi

c - 套接字如何利用100%的网络带宽?

转载 作者:行者123 更新时间:2023-12-02 08:32:01 25 4
gpt4 key购买 nike

我有一个服务器和一个客户端。他们在不同的服务器上工作。两台服务器都有两个1000M网卡

我在服务器和客户端都使用tcp blocking socket

服务器

一旦一个套接字被接受,一个新的线程将被启动来处理请求。它的工作方式如下:

while(1) {
recv(); /* receive a char */
send(); /* send a line */
}

客户端只要向服务器发送一个字符,服务器就会向客户端发送一行文本。文字长度约200。

该行已提前加载到内存中。

客户端

客户端使用不同的线程连接到服务器。连接后,它将像这样工作:

while(1) {
send(); /* send a char */
recv(); /* receive a line and */
}

带宽使用情况

当我在客户端使用 100 个线程时(甚至更多,结果几乎相同),我在服务器中得到这个网络流量:

tsar -l -i 1 --traffic

结果:

Time              -------------traffic------------
Time bytin bytout pktin pktout
06/09/14-23:12:56 0.00 0.00 0.00 0.00
06/09/14-23:12:57 63.4M 155.3M 954.6K 954.6K
06/09/14-23:12:58 0.00 0.00 0.00 0.00
06/09/14-23:12:59 60.1M 147.3M 905.4K 905.4K
06/09/14-23:13:00 0.00 0.00 0.00 0.00
06/09/14-23:13:01 57.5M 140.8M 866.5K 866.4K

sar -n DEV 1:

11:20:46 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
11:20:47 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11:20:47 PM eth0 478215.05 478217.20 31756.46 77744.95 0.00 0.00 0.00
11:20:47 PM eth1 484318.28 484318.28 32162.05 78724.16 0.00 0.00 1.08
11:20:47 PM bond0 962533.33 962535.48 63918.51 156469.11 0.00 0.00 1.08

问题:

理论上(bytin + bytout)的最大值可以是256M。我该如何存档?

任何帮助都会很棒,在此先感谢。

最佳答案

在实践中,在几个层中有一些开销。 1Gbits/sec 以太网在应用程序方面意义不大(但我猜最多 90%)。经验法则是发送recv相当大的数据大小(例如至少几千字节)。发送或接收几百个字节是低效的。而且这个问题肯定是特定于操作系统的(我正在考虑 Linux)。

回想一下,根据定义,TCP 不是数据包的传输,而是字节流的传输。阅读TCP维基页面。您应该避免 sendrecv 几个字节,甚至一百个字节。尝试每次发送 数千个字节。当然,接收方的单个 recv(通常)不对应于发射方的单个 send,反之亦然(特别是如果您之间有一些路由器发送和接收计算机;路由器可以拆分或合并网络数据包,因此您不能确定每个发送器中的每个 send 都在接收器上有一个 recv。/p>

Gigabit Ethernet想要Jumbo Frames将近 9000 字节。您可能希望用于 send 的数据缓冲区略低于该值(因为 IP 和 TCP 的各种开销),因此请尝试 8Kbytes。

send(2)手册页提到 tcp(7)MSG_MORE 标志.你可以小心使用它。另见 this .

还有 syscalls(2)有一些开销。我很惊讶你每秒能做出一百万个。这种开销是将传出和传入数据缓冲成重要片段的另一个原因(例如,每个片段为 8192、16384 或 32768 字节;您需要进行基准测试以找到最佳片段)。如果内核更喜欢页面对齐数据,我不会感到惊讶。所以也许尝试让你的缓冲区对齐到 4096 字节(例如使用 mmap(2)posix_memalign(3) ...)

如果您关心性能,请不要使用 send(2)字节数少。至少将您的应用程序更改为在每次 send 系统调用时发送超过几千字节(例如 4KB)。而对于 recv(2) ,传递一个至少 4KB 的缓冲区。所以 sending 或 recv 单个字节或一行一百个字节是低效的。您的应用程序应该缓冲此类数据(并且可能将数据拆分为“应用程序消息”......)。有一些库这样做(比如 0MQ ...),或者至少用定界符(可能是换行符)终止每条消息,这将简化将接收到的缓冲区拆分为几个传入应用程序消息。

我的感觉是您的应用程序效率低下且存在错误(可能在其他网络上运行不佳,例如,如果两台计算机之间有一些路由器)。您需要重新设计 并重新编码应用程序的某些部分!您需要缓冲,并且需要管理应用程序消息 - 拆分和加入它们....

你应该在几个网络上测试你的应用程序,特别是通过 ADSL 和 wifi,如果可能的话,长距离网络(然后你会观察到 sendrecv 做不是“匹配”)。

关于c - 套接字如何利用100%的网络带宽?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25701775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com