正如标题所述,我有一个用Erlang编写的服务器,一个用Java编写的客户端,它们通过TCP进行通信。我面临的问题是gen_tcp:recv显然不知道何时接收到了来自客户端的“完整”消息,并因此将其“分割”成多个消息。
这是我正在做的示例(不完整的代码,试图仅保留相关部分):
这让我想知道这是否可以在Java端修复?我已经尝试了几种不同的输出流、写入方法和套接字设置组合在服务器端,但是没有任何解决问题的办法。
此外,网络上有很多Erlang(聊天)服务器示例,它们不需要使用任何定界符,尽管这些通常是在两端都使用Erlang编写的。尽管如此,它们似乎假设消息接收方式与发送方式相同。这是不良实践,还是当客户端和服务器都使用Erlang编写时存在一些关于消息长度的隐藏信息?
如果需要定界符检查,我很惊讶为什么找不到更多相关信息。如何以实用的方式完成这项工作呢?
提前感谢您!
这是我正在做的示例(不完整的代码,试图仅保留相关部分):
-module(server).
-export([start/1]).
-define(TCP_OPTIONS, [list, {packet, 0}, {active, false}, {reuseaddr, true}].
start(Port) ->
{ok, ListenSocket} = gen_tcp:listen(Port, ?TCP_OPTIONS),
accept(ListenSocket).
accept(ListenSocket) ->
{ok, Socket} = gen_tcp:accept(ListenSocket),
spawn(fun() -> loop(Socket) end),
accept(ListenSocket).
loop(Socket) ->
case gen_tcp:recv(Socket, 0) of
{ok, Data} ->
io:format("Recieved: ~s~n", [Data]),
loop(Socket);
{error, closed} ->
ok
end.
Java客户端
public class Client {
public static void main(String[] args) {
Socket connection = new Socket("localhost", Port);
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
Scanner sc = new Scanner(System.in);
while(true) {
output.writeBytes(sc.nextLine());
}
}
}
Result
Client
Hello!
服务器
Received: H
Received: el
Received: lo!
我一直在搜索,如果我理解正确的话,TCP不知道消息的大小,需要手动设置某种分隔符。
但是我不明白的是,如果我使用Erlang编写客户端,消息似乎从未分裂,就像这样:
Erlang客户端
-module(client).
-export([start/1]).
start(Port) ->
{ok, Socket} = gen_tcp:connect({127,0,0,1}, Port, []),
loop(Socket).
loop(Socket) ->
gen_tcp:send(Socket, io:get_line("> ")),
loop(Socket).
Result
Client
Hello!
服务器
Received: Hello!
这让我想知道这是否可以在Java端修复?我已经尝试了几种不同的输出流、写入方法和套接字设置组合在服务器端,但是没有任何解决问题的办法。
此外,网络上有很多Erlang(聊天)服务器示例,它们不需要使用任何定界符,尽管这些通常是在两端都使用Erlang编写的。尽管如此,它们似乎假设消息接收方式与发送方式相同。这是不良实践,还是当客户端和服务器都使用Erlang编写时存在一些关于消息长度的隐藏信息?
如果需要定界符检查,我很惊讶为什么找不到更多相关信息。如何以实用的方式完成这项工作呢?
提前感谢您!