tcp - Erlang中socket的 "packet"选项怎么能把tcp传输加速这么多?

标签 tcp erlang ip packet transmission

使用{packet,4}通过本地主机上的两个不同端口传输1G数据仅需8秒,而使用{packet,raw}无法在30秒内完成同一任务。我知道如果使用后一种方法,数据将以数万个小块的形式到达(在 archlinux 上大小为 1460 字节)。我已经了解了 TCP/IP 协议(protocol)的某些方面,并且已经思考这个问题好几天了,但仍然无法弄清楚确切的区别是什么。真诚期待一些自下而上的解释。

-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<br/>
real    0m8.919s
user    0m6.643s
sys     0m2.257s

最佳答案

当你使用 {packet,4} 时,erlang 首先读取 4 个字节来获取数据的长度,分配一个缓冲区来保存它,并在获取每个 tcp 数据包后将数据读入缓冲区。然后它将缓冲区作为一个数据包发送到您的进程。这一切都发生在内置读取代码中,速度相当快。

当你使用 {packet,raw} 时,erlang 在收到每个 tcp 数据包后向你的进程发送一条消息,因此对于每个 tcp 数据包,它会做更多的事情。

关于tcp - Erlang中socket的 "packet"选项怎么能把tcp传输加速这么多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13878587/

相关文章:

c++ - 简单套接字非阻塞 I/O

linux - 连接erlang客户端到oracle

erlang - 从 Vernemq 插件发布消息

php - 如何在 PHP 中为 $_SESSION 设置唯一名称?

java - 使用本地PC作为服务器

networking - TCP Socket 无连接超时

c - tcp 服务器阻塞读取 C

C# 为什么 "Flush"不强制字节通过网络流传输?

server - RabbitMQ启动失败,TCP连接成功但Erlang分发失败

c - 如何使用 IP 的整数值(在 C 中)确定两个 IP 是否位于同一子网中?