java服务器如何知道它收到的消息何时实际结束?
我正在尝试实现一个服务器,当它收到一条消息时,它会这样做:
try{
ObjectInputStream is = new ObjectInputStream(clientSocket.getInputStream());
String message = (String)is.readObject();
ActivateCommand(message,clientSocket);
is.close();
}
和ActivateCommand:
private void ActivateEwolfCommand(String msg, Socket clientSocket) throws IOException
{
ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream());
Gson gsonObject = new Gson();
.
//code which makes a Json string
.
os.writeObject(json);
os.close();
}
现在,当我通过junit测试向本地主机发送消息来测试它时,它工作了。但是,当尝试从C#客户端连接到服务器时,客户端已连接,但服务器在到达clientSocket点时抛出EOF异常。getInputStream()。 我猜这是因为服务器不知道消息应该在什么时候结束,但我不知道是否真的是这样,如果是这样,那么我如何修复它
# 1 楼答案
这就是为什么用套接字和对象流创建自己的客户机-服务器协议是个坏主意。很多人花了很多年的时间带你来,哦,好吧:
还有很多其他的协议。当然,其中一个,如果不是5或6,就足以解决你的问题,包括所有的框架问题
# 2 楼答案
如果希望通过套接字发送字符串,那么
ObjectInputStream
或ObjectOutputStream
不是正确的流实现。这些流实现使用Java对象序列化。即使序列化String
实例,得到的字节也不同于使用适当字符编码的普通字符串到字节的转换C#应用程序根本不理解Java序列化
考虑使用^ {< CD4>}将字符串写入流,并使用^ {CD5>}进行读取。
然后你可以逐行读写字符串。 这只是一个起点。如果你想实现你自己的协议,你必须注意更多的要点。例如,您可以阅读一些TCP协议的规范,如POP3、FTP或HTTP 1.0
# 3 楼答案
当
InputStream
到read()
上没有更多可用数据时,这基本上就是导致EOF的原因。有多少数据是可用的由客户端决定的-它写入套接字OutputStream
的数据在服务器端的InputStream
套接字上显示为可用数据。您可以调用InputStream.available()
来获得仍然是read()
的字节数的估计值但是,您的代码尝试使用ObjectInputStream读取对象-此类有自己的协议来读取序列化字节流并将其转换为对象-如果找不到完成任务的字节,则可能引发EOF异常。如果您的客户机是C#-那么为序列化对象写入的字节格式肯定与服务器端的
ObjectInputStream
所期望的不一样