1

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

这就是我想要做的:

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

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

Erlang 版本:R14B01 (erts-5.8.2)

更新

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

4

3 回答 3

4

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

这可能是正在发生的事情,因为当您关闭套接字时,它会在释放之前被刷新。

尝试设置

{nodelay, true}

插座上的选项。

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

于 2011-09-12T07:14:56.473 回答
3

主要问题是没有通用消息格式。因此,您的第一步是找到服务器使用的消息格式。您无法使用其他语言与服务器交谈。

一些消息格式可以是:

  • 整个流是一条消息。
  • 固定大小的消息。
  • 由标记分隔的消息。例如SMTPPOPHTTP和许多其他协议都使用这种类型的消息。
  • 带有大小字段的消息。例如TLV(类型-长度-值)消息格式。IPUDPErlang和许多其他协议都使用这种类型的消息。

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

1> {ok, S} = gen_tcp:connect(IP, Port, []).
2> gen_tcp:send(S, "Test\n").
3> gen_tcp:send(S, "Test2\n").
于 2011-09-09T21:20:29.340 回答
1

你可以在 Erlang 服务器上尝试一下,看看是服务器端还是客户端有问题。

在外壳 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

在外壳 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 方面的问题。

于 2011-09-09T07:12:27.487 回答