使用gen_tcp:send的消息在套接字关闭之前不会被发送

时间:2011-09-08 18:56:03

标签: java sockets erlang gen-tcp

我想编写一个简单的客户端,它将消息发送到服务器并接收响应。我有一台服务器向所有连接的客户端广播相同的消息,当我用telnet测试它时它正在工作。当我尝试使用Erlang shell时,gen_tcp:发送不会发送任何消息,直到我关闭套接字。

这就是我要做的事情:

{ok, S} = gen_tcp:connect(IP, Port, []).
gen_tcp:send(S, "Test").
flush().

我可以看到,当我通过查看我的telnet客户端关闭套接字时,会发送消息。

  

Erlang版本:R14B01(erts-5.8.2)

更新

hdima评论说,服务器如何从流中提取消息可能是错误的。这似乎是因为当我尝试编写自己的服务器时,客户端似乎按预期工作。我将尝试获取服务器的源代码。服务器是用Java编写的。

3 个答案:

答案 0 :(得分:3)

当发送小块数据时,套接字将它们缓冲起来以尝试填充TCP数据包的最大有效负载。

这可能是正在发生的事情,因为当你关闭套接字时,它会在被解除分配之前被刷新。

尝试设置

{nodelay, true}

上的

选项。

更多信息: http://www.erlang.org/doc/man/inet.html#setopts-2

答案 1 :(得分:1)

主要问题是没有通用邮件格式。所以你的第一步是找到服务器使用的消息格式。您无法使用其他语言与服务器通话。

某些消息格式可以是:

  • 整个流是一条消息。
  • 固定尺寸​​信息。
  • 由标记分隔的邮件。例如SMTPPOPHTTP和许多其他协议都使用此类消息。
  • 包含尺寸字段的消息。例如TLV (Type-Length-Value)消息格式。 IPUDPErlang和许多其他协议都使用此类消息。

例如,如果服务器理解换行符分隔的消息,您可以使用以下代码发送两条不同的消息:

1> {ok, S} = gen_tcp:connect(IP, Port, []).
2> gen_tcp:send(S, "Test\n").
3> gen_tcp:send(S, "Test2\n").

答案 2 :(得分:0)

您可以尝试使用Erlang服务器来查看是否存在问题的服务器端或客户端。

在shell A中:

1> {ok, L} = gen_tcp:listen(12345, [{active, false}]).
{ok,#Port<0.601>}
2> {ok, S} = gen_tcp:accept(L), {ok, P} = gen_tcp:recv(S, 0), gen_tcp:send(S, P).
... % Server will block here until a message comes
ok

在shell B中:

1> {ok, S} = gen_tcp:connect(localhost, 12345, []), gen_tcp:send(S, "hello").
ok
2> flush().
Shell got {tcp,#Port<0.607>,"hello"}

如果这样做,那很可能是Java方面的一个问题。