我正在编写一个应该从服务器接收文件的客户端应用程序。通信使用基于 TCP 设计的非常简单的专有协议(protocol):服务器发送一个 16KB 的数据 block ,等待来 self 的客户端的简单响应,然后继续下一个数据 block ;这样做直到文件被完全传输。
服务器在 Windows 上运行。如果我在 Windows 上运行我的客户端(通过 Cygwin),我可以达到 70Mbits/s 的吞吐量。但是,如果我在 Linux 上运行它,我可以获得的最大吞吐量是 5Mbits/s(两个测试都使用相同的 100Mb 以太网链路)。
在对我收集的 tcpdump 跟踪进行一些调查后,我发现 Linux 大约需要 10 毫秒来回答每个 TCP ACK。每次调用 recv() 后,我都尝试禁用 sockoption TCP_QUICKACK,但没有成功。我还没有找到任何其他可以改变这种行为的 TCP 选项(在 bsd 套接字下,甚至在 Linux 下)。
谁能帮我弄清楚发生了什么?
下面是我分析的 tcpdump 跟踪示例。这是 block 传输。服务器IP为10.200.252.1,客户端为10.200.252.2。以**开头的行是延迟10ms的TCP ACK数据包:
5184 28.060969 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4736738 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5185 28.060978 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4738182 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5186 28.060981 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4739626 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5187 28.060987 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4741070 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5188 28.060990 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4742514 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5189 28.060994 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4743958 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5190 28.060997 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4745402 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5191 28.061000 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4746846 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5192 28.061003 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4748290 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5193 28.061007 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4749734 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5194 28.061038 10.200.252.1 10.200.252.2 TCP 1510 search-agent > 58358 [ACK] Seq=4751178 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
5195 28.061042 10.200.252.1 10.200.252.2 TCP 572 search-agent > 58358 [PSH, ACK] Seq=4752622 Ack=1741 Win=66048 Len=506 TSval=2951472 TSecr=2921060
**5196 28.068422 10.200.252.2 10.200.252.1 TCP 66 58358 > search-agent [ACK] Seq=1741 Ack=4742514 Win=64512 Len=0 TSval=2921061 TSecr=2951472
**5197 28.078479 10.200.252.2 10.200.252.1 TCP 66 58358 > search-agent [ACK] Seq=1741 Ack=4753128 Win=64512 Len=0 TSval=2921062 TSecr=2951472
5198 28.082418 10.200.252.2 10.200.252.1 TCP 70 58358 > search-agent [PSH, ACK] Seq=1741 Ack=4753128 Win=64512 Len=4 TSval=2921062 TSecr=2951472
5199 28.082675 10.200.252.2 10.200.252.1 TCP 68 58358 > search-agent [PSH, ACK] Seq=1745 Ack=4753128 Win=64512 Len=2 TSval=2921062 TSecr=2951472
5200 28.082714 10.200.252.1 10.200.252.2 TCP 66 search-agent > 58358 [ACK] Seq=4753128 Ack=1747 Win=66048 Len=0 TSval=2951474
最佳答案
完全摆脱分 block 和应用程序 ACK。如果必须的话,在文件末尾放最后一个。 TCP 已经进行了分 block 和 ACK,你正在把它逼疯,例如它必须对 ACK 进行 ACK。不需要所有这些复杂性。这是一种流式传输协议(protocol):像使用它一样使用它。
关于linux - TCP ACK 响应延迟 10ms,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17845000/
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
是否可以在所有delayed_job任务之前运行一个方法?基本上,我们试图确保每个运行delayed_job的服务器都有我们代码的最新实例,所以我们想运行一个方法来在每个作业运行之前检查它。(我们已经有了“check”方法并在别处使用它。问题只是关于如何从delayed_job中调用它。) 最佳答案 现在有一种官方方法可以通过插件来做到这一点。这篇博文通过示例清楚地描述了如何执行此操作http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文中描述
我刚刚安装了带有RVM的Ruby2.2.0,并尝试使用它得到了这个:$rvmuse2.2.0--defaultUsing/Users/brandon/.rvm/gems/ruby-2.2.0dyld:Librarynotloaded:/usr/local/lib/libgmp.10.dylibReferencedfrom:/Users/brandon/.rvm/rubies/ruby-2.2.0/bin/rubyReason:Incompatiblelibraryversion:rubyrequiresversion13.0.0orlater,butlibgmp.10.dylibpro
我正在运行Ubuntu11.10并像这样安装Ruby1.9:$sudoapt-getinstallruby1.9rubygems一切都运行良好,但ri似乎有空文档。ri告诉我文档是空的,我必须安装它们。我执行此操作是因为我读到它会有所帮助:$rdoc--all--ri现在,当我尝试打开任何文档时:$riArrayNothingknownaboutArray我搜索的其他所有内容都是一样的。 最佳答案 这个呢?apt-getinstallri1.8编辑或者试试这个:(非rvm)geminstallrdocrdoc-datardoc-da
我已经通过提供MagickWand.h的路径尝试了一切,我安装了命令工具。谁能帮帮我?$geminstallrmagick-v2.13.1Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingrmagick:ERROR:Failedtobuildgemnativeextension./Users/ghazanfarali/.rvm/rubies/ruby-1.8.7-p357/bin/rubyextconf.rbcheckingforRubyversion>=1.8.5...yescheckingfor/
我正在使用macos,我想使用ruby驱动程序连接到sqlserver。我想使用tiny_tds,但它给出了缺少free_tds的错误,但它已经安装了。怎么能过这个?~brewinstallfreetdsWarning:freetds-0.91.112alreadyinstalled~sudogeminstalltiny_tdsBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtiny_tds:ERROR:Failedtobuildgemnativeextension.完整日志如下:/System
我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat
如何解决这个错误:$rvminstall1.9.3Searchingforbinaryrubies,thismighttakesometime.Nobinaryrubiesavailablefor:osx/10.9/x86_64/ruby-1.9.3-p547.Continuingwithcompilation.Pleaseread'rvmhelpmount'togetmoreinformationonbinaryrubies.Checkingrequirementsforosx.Certificatesin'/usr/local/etc/openssl/cert.pem'arealr
下载微PE工具箱进入官网下载微PE工具箱-下载 安装好后,打开微PE工具箱客户端,选择安装PE到U盘 PE壁纸可选择自己喜欢的壁纸,勾选上包含DOS工具箱,个性化盘符图标 下载原版系统进入网站下载镜像NEXT,ITELLYOU如果没有账号,注册一下就好进入选择开始使用选择win10 这里我们选择消费者版,用迅雷把BT种子下载下来 下面的两个盘符,是PE工具箱安装进U盘后,分成的盘符,注意EFI的盘符,这里面不能删东西,也不能添东西,另一个盘符可以当做正常的U盘空间使用,我们现在需要把下载下来的景象文件复制到正常的U盘空间中去 这个时候我们的系统U盘就只做好了 安装系统我们将U盘插入电脑,开机,