“分组”如何在Erlang中插座的选项加速了tcp传输呢? [英] How can the "packet" option of socket in Erlang accelerate the tcp transmission so much?

查看:146
本文介绍了“分组”如何在Erlang中插座的选项加速了tcp传输呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用{packet,4}在localhost上通过两个不同端口传输1G数据只需8秒,而使用{packet,raw}的同一任务在30秒内无法完成。我知道如果使用后一种方法,数据会到达成千上万的小块(archlinux的大小是1460字节)。我已经学习了TCP / IP协议的一些方面,并且一直在考虑这个问题,但仍然无法弄清楚什么是EXACT差异。真诚期待一些自下而上解释。

It takes only 8 seconds to transfer 1G data through two different ports on localhost using {packet,4}, while the same task can't be finished within 30 seconds using {packet,raw}. I know if use the latter method, the data will arrive in tens of thousands small pieces (on archlinux the size is 1460 bytes). I've learned some aspects of TCP/IP protocol and have been thinking about this question for days but still can't figure out what is the EXACT difference. Sincerely look forward to some bottom-up explanation.

-module(test).

-export([main/1]).

-define(SOCKOPT, [binary,{active,true},{packet,4}]).

main(_) ->
    {ok, LSock} = gen_tcp:listen(6677, ?SOCKOPT),
    spawn(fun() -> send() end),
    recv(LSock).

recv(LSock) ->
    {ok, Sock} = gen_tcp:accept(LSock),
    inet:setopts(Sock, ?SOCKOPT),
    loop(Sock).

loop(Sock) ->
    receive
        {tcp, Sock, Data} ->
            io:fwrite("~p~n",[bit_size(Data)]),
            loop(Sock);
        {tcp_closed, Sock} -> ok
    end.

send() ->
    timer:sleep(500),
    {ok, Sock}=gen_tcp:connect("localhost", 6677, ?SOCKOPT),
    gen_tcp:send(Sock, binary:copy(<<"1">>, 1073741824)),
    gen_tcp:close(Sock).

$ time escript test.erl
8589934592
real 0m8.919s user 0m6.643s sys 0m2.257s

推荐答案

当数据接收到小块时,接收端的内核缓冲区会快速填满。它将减少发送方的拥塞窗口大小,迫使发送方以较低的速率推送数据。

When the data is received in small pieces, the kernel buffer at receiver end fills up fast. It will reduce the congestion window size at sender side forcing the sender to push data at lower rate.

这篇关于“分组”如何在Erlang中插座的选项加速了tcp传输呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆