Erlang / Golang 端口示例中的缓冲区大小

2024-03-29

我有一个粗略的 Erlang-to-Golang 端口示例,将数据从 Erlang 传递到 Golang 并回显响应。

问题是我可以传输的数据量似乎仅限于 2^8 字节(见下文)。我认为问题可能出在 Golang 方面(没有创建足够大的缓冲区),但是用 bufio.NewReaderSize 替换 bufio.NewReader 不起作用。所以我现在认为问题可能出在 Erlang 方面。

我需要做什么来增加缓冲区大小/能够回显大于 2^8 字节的消息?

TIA

justin@justin-ThinkPad-X240:~/work/erlang_golang_port$ erl -pa ebin
Erlang/OTP 17 [erts-6.4.1] [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false]

Eshell V6.4.1  (abort with ^G)
1> port:start("./echo").
<0.35.0>
2> port:ping(65000).
65000
3> port:ping(66000).
** exception error: bad argument
     in function  port:call_port/1 (port.erl, line 20)
4> port:start("./echo").
<0.40.0>
5> port:ping(66000).    
65536

Go

package main

import (
    "bufio"
    "os"
)

const Delimiter = '\n'

func main() {
    // reader := bufio:NewReader(os.Stdin)
    reader := bufio.NewReaderSize(os.Stdin, 1677216) // 2**24;
    bytes, _ := reader.ReadBytes(Delimiter)
    os.Stdout.Write(bytes[:len(bytes)-1])
}

Erlang

-module(port).

-export([start/1, stop/0, init/1]).

-export([ping/1]).

-define(DELIMITER, [10]).

start(ExtPrg) ->
    spawn(?MODULE, init, [ExtPrg]).

stop() ->
    myname ! stop.

ping(N) ->
    Msg=[round(65+26*random:uniform()) || _ <- lists:seq(1, N)],
    call_port(Msg).

call_port(Msg) ->
    myname ! {call, self(), Msg},
    receive
    {myname, Result} ->
        length(Result)
    end.

init(ExtPrg) ->
    register(myname, self()),
    process_flag(trap_exit, true),
    Port = open_port({spawn, ExtPrg}, []),
    loop(Port).

loop(Port) ->
    receive
    {call, Caller, Msg} ->
        Port ! {self(), {command, Msg++?DELIMITER}},
        receive
        {Port, {data, Data}} ->
            Caller ! {myname, Data}
        end,
        loop(Port);
    stop ->
        Port ! {self(), close},
        receive
        {Port, closed} ->
            exit(normal)
        end;
    {'EXIT', Port, _Reason} ->
        exit(port_terminated)
    end.

如果你使用start_link相反,您会看到第一个命令后端口崩溃:

1> port:start('go run port.go').
<0.118.0>
2> port:ping(65000).
65000
** exception error: port_terminated

如果将 Go 代码更改为循环运行,则可以避免此崩溃:

func main() {
    for {
        // reader := bufio:NewReader(os.Stdin)
        reader := bufio.NewReaderSize(os.Stdin, 1677216) // 2**24;
        bytes, _ := reader.ReadBytes(Delimiter)
        os.Stdout.Write(bytes[:len(bytes)-1])
    }
}

现在我们可以看到另一个有趣的结果:

33> c(port).
{ok,port}
40> port:ping(66000).
65536
41> port:ping(66000).
464
42> port:ping(66000).
65536
43> port:ping(66000).
464

现在我们可以看到实际上没有数据丢失,它只是缓冲在端口中。由于您尚未指定成帧协议(使用{packet, N} or {line, N}您自行负责收集数据。 Erlang 端口的内部缓冲区大小似乎也是 64K(尽管我没有找到这方面的文档,也没有办法更改它)。

如果您将接收更改为在返回之前获取所有数据,则每次都会获取每个字节:

loop(Port) ->
    receive
    {call, Caller, Msg} ->
        Port ! {self(), {command, Msg++?DELIMITER}},
        Caller ! {myname, receive_all(Port, 10)},
        loop(Port);
    stop ->
        Port ! {self(), close},
        receive
        {Port, closed} ->
            exit(normal)
        end;
    {'EXIT', Port, _Reason} ->
        exit(port_terminated)
    end.

receive_all(Port, Timeout) -> receive_all(Port, Timeout, []).

receive_all(Port, Timeout, Data) ->
    receive
    {Port, {data, New}} ->
        receive_all(Port, Timeout, [New|Data])
    after Timeout ->
        lists:flatten(lists:reverse(Data))
    end.

运行这个,我们得到:

1> c(port).
{ok,port}
2>
3> port:start('go run port.go').
<0.311.0>
4> port:ping(66000).
66000
5> port:ping(66000).
66000
6> port:ping(66000).
66000
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Erlang / Golang 端口示例中的缓冲区大小 的相关文章

随机推荐

  • 仅当用户启用了 JavaScript 时才使用一些 CSS

    为了让我的网页正常降级 我有一些 CSS 只有在其相应的 JavaScript 能够运行时才应该加载它们 当且仅当浏览器启用了 JavaScript 时 加载本地 CSS 的最简单方法是什么 而且它是一个相当大的 CSS 块 所以我不想编写
  • 使用 WinHttp 发布表单

    在向服务器发布帖子之前我需要添加任何标头吗 例如 目前我正在尝试以这种方式发送请求和发布数据 LPCWSTR post L name User subject Hi message Hi if WinHttpSendRequest hReq
  • 微软图表:透明度

    我想要一个具有透明背景的图表 因此 PNG 似乎是一个不错的选择 但是当我设置透明背景时 轴标签的质量急剧下降 我该如何解决 请参阅以下代码 就目前情况而言 图表具有透明背景 正如我所希望的那样 但文本质量很差 如果我注释掉两个 Color
  • 使用 Windows 窗体在脚本终止后几分钟锁定 PowerShell ISE

    我这里有一个有趣的问题 我正在创建一个日历选择器 供我们创建帐户时使用 它工作正常并且仍在进行中 但我注意到当我在 powershell ISE 中运行脚本时 几分钟后它会锁定 我可以在此之前编辑并保存代码几分钟 事件日志中没有任何内容 我
  • ng-animate :模型更改时的动画

    我创建了一个表 用户可以在其中增加和减少值 请参阅Fiddle http jsfiddle net AnandVishnu c5p39 sample code as its not allowing me to push the link
  • 面向对象的程序员如何了解数据库驱动的编程?

    我已经使用 C 和 Java 编程一年多了 并且对面向对象编程有了很好的掌握 但是我的新副项目需要数据库驱动的模型 我正在使用 C 和 Linq 这似乎是一个非常强大的工具 但我在围绕面向对象的方法设计数据库时遇到了麻烦 我的两个主要问题是
  • 引导导航栏崩溃在计算机上工作而不是在iPhone上工作

    当我将计算机屏幕大小调整到 980 像素以下时 我的固定导航栏工作正常 一旦我的屏幕达到 979 像素或更小 导航栏折叠就会启动并完美运行 然而 当我将代码推送到 Heroku 并在 iPhone 4S 上加载该网站时 我的导航栏不仅没有折
  • 在 aws 微实例上安装 redis

    我需要在亚马逊云中安装redis 我需要它作为我的 npm 模块 kue 部署 的一部分 考虑到我对 Linux 和管理的了解并不好 任何人都可以链接我的逐步教程或解释如何做到这一点 如果您启用 Amazon Linux 上存在的 Extr
  • 通过按同一个按钮来打开/关闭 MapKit 叠加?

    我有一个带有工具栏按钮的 MapView 按下该按钮时会向 MapView 添加叠加层 我想要的是按钮 IBAction 检查地图上是否已经有覆盖物 如果有 则删除 如果没有 则添加它们 我当前添加叠加层的代码如下 IBAction wat
  • JacksonFeature 破坏了 JsonIgnoreProperties

    我有这样的 pojo JsonIgnoreProperties ignoreUnknown true public class SNAPIResponse public String status public String message
  • Keras:从 ImageDataGenerator 或 Predict_generator 获取真实标签 (y_test)

    我在用ImageDataGenerator flow from directory 从目录生成批量数据 模型成功构建后 我想获得真实和预测类标签的两列数组 和model predict generator validation genera
  • 在mawk中使用strftime函数

    我正在尝试创建 AWK 脚本 该脚本将根据某种模式过滤输入文件 并使用 strftime 函数进行一些计算 2 HB 2 n print strftime Y 使用的解释器是mawk 使用此命令触发此脚本时 awk f script3 in
  • 使用curl将文件推送到GitHub存储库

    我想在 GitHub 存储库上创建 推送 新文件 而不需要git工具 因为git我的工具不可用PHP主持人 所以我做了一些研究 发现GitHub REST API https docs github com en rest 我尝试使用cur
  • 电池的最佳使用

    作为一名程序员 我可以采取哪些措施来确保我的应用程序不会占用大量资源并耗尽电池 根据您正在编写的应用程序 其中一些可能适用于您 不要使用过多的网络调用 尝试维护不经常更改的数据缓存 并且仅在上次刷新 10 秒后运行完全刷新 阻止它们向服务器
  • SQLite Swift 中有多少种方式进行 CRUD 操作?

    当我在 SQLite 中进行 CRUD 操作时 我很困惑 因为有人对我说你可以使用 FMDB 库进行 CRUD 操作 有人说 GRDB 所以 我的问题是 在 SQLite 中有多少种方法可以进行 CRUD 操作 哪种方法是正确的 我认为 G
  • 如何在 Jquery 验证中处理 html 元素 id/name 中的特殊字符?

    我有一个 HTML 表单 它在 ids 中使用特殊字符 该表单使用 JQuery 验证插件来验证用户输入 具体来说 id 包括 GUID 以下是示例代码
  • 在 Eclipse 中,Source -> Format 在“Maven Pom Editor”中被禁用

    当打开pom xml在 Eclipse 中使用 Maven Pom Editor 并切换到选项卡pom xml我无法格式化该文件 Hitting Ctrl Shift F在完全未格式化的文件中不会执行任何操作 通过上下文菜单时Source
  • Python 中的递归、记忆和可变默认参数

    Base 的意思是不只使用lru cache 所有这些都 足够快 我并不是在寻找最快的算法 但时间安排让我感到惊讶 所以我希望我能了解一些有关 Python 如何 工作 的知识 简单循环 尾递归 def fibonacci n a b 0
  • Flask 应用偶尔挂起

    我一直在开发一个 Flask 应用程序 它使用 Twilio 处理 SMS 消息 将它们存储在数据库中 并通过 JSONP GET 请求提供对前端的访问 我已经使用supervisord对其进行了守护进程 这似乎工作得很好 但每隔几天它就会
  • Erlang / Golang 端口示例中的缓冲区大小

    我有一个粗略的 Erlang to Golang 端口示例 将数据从 Erlang 传递到 Golang 并回显响应 问题是我可以传输的数据量似乎仅限于 2 8 字节 见下文 我认为问题可能出在 Golang 方面 没有创建足够大的缓冲区