问题标签 [gen-tcp]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
387 浏览

sockets - Erlang gen_tcp:recv socket closing

I am working in project with websockets and MQTT. Websocket server receives 4 messages from mqtt and I made it loop to receive any other messages. However, if there are no messages, Encoded_fixed_header = gen_tcp:recv(Socket, 0) gives an error because there are no messages to receive. I did some research on gen_tcp:recv and it says that it waits infinitely for a message, but it seems not and it closes the socket.

What could be the problem?

0 投票
1 回答
767 浏览

sockets - Erlang:使用 sockets/gen_tcp 连接到 API

我是 erlang 和整体编程的新手,我正在寻找一种通过使用套接字连接到 twitter API 的方法,如果有的话。所以我想知道的是,无论如何要在套接字中传递http请求/ URL来这样做吗?

我很想阅读或查看任何信息。示例代码,我可以在其中看到 gen_tcp、socket、ssl 或任何您认为最聪明的方法。(连接到推特/发送请求)。

除非我真的需要,否则我不希望使用另一个构建的库。

提前致谢, 埃拉赫

0 投票
2 回答
1865 浏览

erlang - gen_tcp的passive和once模式的区别

我正在阅读Programming Erlang 2E。在第 17 章的主动和被动套接字中,它说:

您可能认为对所有服务器使用被动模式是正确的方法。不幸的是,当我们处于被动模式时,我们只能等待来自一个套接字的数据。这对于编写必须等待来自多个套接字的数据的服务器是没有用的。

幸运的是,我们可以采用混合方法,既不是阻塞也不是非阻塞。我们使用选项 {active, once} 打开套接字。在这种模式下,套接字是活动的,但只有一条消息。在向控制进程发送消息后,它必须显式调用 inet:setopts 以重新启用下一条消息的接收。系统将阻塞,直到发生这种情况。这是两全其美的。

相关代码:

我看不出两者之间有什么真正的区别。gen_tcp:recvin mode 本质上与in passivemode 做同样的事情。模式如何解决模式的这个问题:receiveonceoncepassive

不幸的是,当我们处于被动模式时,我们只能等待来自一个套接字的数据。这对于编写必须等待来自多个套接字的数据的服务器是没有用的。

0 投票
1 回答
263 浏览

sockets - 接收未知的字符串长度?

所以我正在将我写的一个Python程序转换成Erlang,而我已经很久没有使用Erlang了。所以我客人我回到了初学者的水平。无论如何,根据经验,我在处理套接字时使用的每种语言都有发送/接收函数,这些函数总是返回发送/接收数据的长度。然而,在 Erlangs gen_tcp 的情况下,似乎并没有这样做。

因此,当我调用 send/recv/或 inet:setopts 时,它知道数据包何时结束?我是否需要编写一个循环的 recvAll/sendAll 函数,以便在我希望接收的数据包(字符串)中找到转义符或 \n?

http://erlang.org/doc/man/gen_tcp.html#recv-2

我正在使用的示例代码:

仅通过查看示例和文档,Erlang 似乎就知道了。我想确认一下,因为接收到的数据长度可以在 20 字节到 9216 字节之间,或者可以分块发送,因为客户端是我正在编写的 PHP 套接字库。

谢谢,

阿杰姆。

0 投票
1 回答
508 浏览

erlang - Erlang gen_tcp:recv http_request abs_path

我正在用 Erlang 编写接受 HTTP 请求的代码。我有如下所示的工作代码。

我遇到的问题是我不确定gen_tcp:recv.

我创建了一个监听套接字并使用接受套接字

我接受 GET 请求(或任何其他请求)

然后,要获取 url 参数(CGI 参数,例如?foo=1&bar=2),我必须匹配Path一个结构{abs_path, RelativePath}

当我阅读 Erlang 的文档时gen_tcp,更具体地说,recv我找到了描述HttpPacket.

页面上的语法清楚地表明Pathin HttpPacket,在这种情况下是HttpRequest类型,可以有多种类型HttpUri

我知道我必须支持每一种可能的情况,但我不确定。我也想知道如何测试这些案例。我曾尝试在 Firefox 中使用curlandRESTClient并且它们都gen_tcp:recv返回abs_path

所以要明确一点,如何确定请求是否成立{abs_path, HttpString}{scheme, Scheme :: HttpString, HttpString}或者{absoluteURI,...}我是否需要支持所有这些?

完整列表

0 投票
1 回答
188 浏览

sockets - 在 Erlang 中通过 RPC 在远程节点上创建套接字时,无法接受套接字上的连接

我正在努力找出 gen_tcp:accept 总是返回 {error, closed} 响应的原因。

本质上,我有一个创建监听套接字的主管:

然后这个套接字被传递给一个子节点,它是 gen_server 行为的一个实现。然后孩子接受套接字上的连接。

我在本地加载 supervisor 和 gen_server BEAM 二进制文件,并通过对 code:load_binary 的 RPC 调用将它们加载到另一个节点(在同一台机器上运行)。接下来,我通过 RPC 调用执行主管,然后启动服务器。{error, closed} 在这种情况下总是由 gen_tcp:accept 返回。

如果我在登录到节点外壳时运行主管和服务器,那么服务器可以毫无问题地接受连接。这包括对无法接受连接的远程节点的“remsh”,如果我之前对其进行了 RPC 以不成功地启动服务器。

我似乎能够通过单独使用 shell 来复制这个问题:

对最终 RPC 的响应是 {error, closed}。

这可能与套接字/端口所有权有关吗?

万一它有帮助,没有客户端等待连接,我也没有在任何地方设置超时。

0 投票
1 回答
436 浏览

erlang - Gen_tcp over gen_server socket 监听立即关闭

我想在 gen_server 上使用 gen_tcp,代码如下:

好吧,tcp_listener之前立即关闭waitConnetion,我真的不明白为什么。

如果我handle_cast在 init 部分移动代码,它可以正常工作。

为什么连接被关闭?我花了很多时间没有成功。

任何帮助表示赞赏。

编辑

如果我在听众之后移动演员代码:

我发布的代码:

0 投票
1 回答
1315 浏览

erlang - Erlang TCP 套接字关闭

为了学习 Erlang,我正在尝试实现一个基于gen_tcp. 不幸的是,我的代码似乎触发了一些有线行为。为了演示这个问题,我附上了我的实现的最小化版本,它足以重现问题。无论 HTTP 请求是什么,它都只是提供静态 200 OK。

当我尝试ab对我的 Web 服务器(使用环回接口)运行(Apache HTTP 服务器基准测试)时,就会出现问题。没有任何并发​​请求(-c),一切都运行得很好。但是,如果我使用-c 8or -c 16,调用 togen_tcp:accept/1似乎在某些套接字上失败,因为我request: closed在 shell 中看到了许多行。

让整个故事更奇怪的是,我在不同的操作系统上看到了不同的行为:

  • OS X+Erlang/OTP 18:ab启动后几乎立即报告“对等方重置连接”。
  • Debian+Erlang R15B01:除了两个 HTTP 请求之外的所有请求似乎都通过了。但是ab,当我ab使用-n 5000. 同样,当我运行 15000 次测试时报告 14998。

似乎不是问题。老实说,我很迷茫,因此感谢任何帮助!:) 谢谢!

0 投票
1 回答
962 浏览

sockets - Erlang同时连接1M客户端

我有一个问题:我想创建一个可以容纳 1M 同时打开的 tcp 连接的 Erlang 服务器。我调整了我的操作系统(Oracle Linux 7)来提升文件描述符。在服务器上我做 gen_tcp:listen

// point_1
Socket = gen_tcp:accept
spawn(handle(Socket)) // 另一个线程
回到 point_1

如果我按顺序连接没问题,在 100 秒内我连接了 10 万个客户端;但我没有耐心等待更多。

例如,如果我想以一种并发的方式连接它们,那么只有大约 80 个连接来自 100 个。

这就是我运行一切的方式:

// 启动一台服务器,监听 9999 端口

// 100 个客户端尝试连接端口 9999

让我给你看一些代码:

0 投票
1 回答
823 浏览

sockets - 由于端口命令没有返回,进程在 gen_tcp send/2 中被阻止

编辑于 2015-11-25 02:10

我的 ejabberd 版本是 14.12 和 erlang R17B,所以这段代码似乎没用,因为 R17B 中的 erlang:system_info(otp_release) 重新运行“17”

ejabberd_listener.erl

我在监听选项中手动添加了 {send_timeout_close, true},我的问题似乎得到了解决,因为套接字在发送超时的同时关闭,尝试在队列中发送后续消息会收到 {error,enotconn} 响应。当 {gen_event, 'closed'} msg 来临时,c2s 进程正常终止。

编辑于 2015-11-24 03:40



也许我找到了重现此问题的方法:
1. 与 xmpp 客户端建立正常的 c2s 连接
2. 使用一些工具切断客户端的网络,例如。笨拙(从服务器丢弃所有 tcp 数据包)
3. 继续向 c2s 进程发送大数据包

首先,gen_tcp:send 在 sendbuffer 填充之前返回 ok
然后,gen_tcp:send 重新运行 {error,timeout} 因为 sendbuffer 已填充
进程调用 ejabberd_socket:close(Socket) 关闭连接

结尾;

但是 ejabberd_socket:close/1 似乎是一个异步调用,所以 c2s 进程会处理 message_queue 中的下一条消息,继续调用 gen_tcp:send/2,等待一个 send_timeout。
但是此时ejabberd_receiver调用了gen_tcp:close(Socket),socket关闭了,所以之前的gen_tcp:send/2永远不会返回。我已经用这种方法尝试了几次,它发生了 100%。


简而言之,如果我将数据包发送到无法接收数据包的客户端套接字并且发送缓冲区已满,我会在发送超时后收到{错误,超时}。但是,如果另一个异步进程在我等待 gen_tcp:send/2 的发送超时时关闭了套接字,我将永远不会得到响应。

所以,我用 erl 做了这个,而 gen_tcp:send/2 没有响应(在第 3 步切断网络,继续发送数据包,异步关闭)。我想知道这是一个问题还是因为我自己的原因? 在此处输入图像描述




下面是原帖


通常在 ejabberd 中,我将消息路由到客户端进程,通过此函数发送到 tcp 套接字。它在大多数时候都运行良好。 模块 ejabberd_c2s.erl

但在某些情况下,c2s pid 像这样在 gen_tcp:send 上阻塞

大多数情况发生在用户的网络状态不太好时,接收进程应该向 c2s pid 发送 2 条消息,c2s 将终止会话或等待恢复

{'$gen_event',关闭}
{'DOWN',#Ref<0.0.1201.250595>,进程,<0.19617.245>,正常}

我在c2s进程中打印了消息队列,2个消息在队列中,等待处理。不幸的是,队列不再移动,因为进程在处理这些消息之前已经阻塞,如上所述,在尝试执行 gen_tcp:send/2 时堆叠在 prim_inet:send/3。几天后队列变得非常大,当进程要求更多内存时,ejabberd 崩溃。


似乎端口驱动程序在 erlang:port_command(S, Data, OptList) 之后没有回复 {inet_reply,S,Status} 。gen_tcp:send 函数会阻塞无穷大,谁能解释一下?