0

我正在尝试实现一个服务器,它在收到消息时会执行以下操作:

try{
       ObjectInputStream is = new ObjectInputStream(clientSocket.getInputStream());
       String message = (String)is.readObject();
       ActivateCommand(message,clientSocket);
       is.close();
    }

和激活命令:

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.getInputStream() 点时抛出 EOF 异常。我猜这是因为服务器不知道消息何时结束,但我不知道是否真的如此,如果是,那么我该如何解决?

4

3 回答 3

0

InputStream当to上没有更多可用数据时read()- 这基本上就是导致 EOF 的原因。有多少可用数据由客户端决定 - 它写入OutputStream 其一侧InputStream的 Socket 的数据在服务器端的 Socket 上显示为这样。您可以调用InputStream.available()以估计可以静止的字节数read()

但是,您的代码正在尝试使用 ObjectInputStream 读取对象-此类具有自己的协议来读取序列化的字节流并将其转换为对象-如果它找不到完成任务的字节,则可能会引发 EOF 异常。如果您的客户端使用 C# - 为序列化对象写入的字节格式肯定ObjectInputStream与服务器端预期的不同。

于 2012-05-29T21:36:18.250 回答
0

这就是为什么使用套接字和对象流创建自己的客户端-服务器协议是一个坏主意的原因。很多人花了很多年给你带来,哦,好吧:

  • 肥皂
  • 休息
  • RMI
  • 黑森州
  • 科尔巴
  • 节约

以及许多其他协议。当然,如果不是 5 或 6 个,其中之一足以解决您的问题,包括所有框架问题。

于 2012-05-29T21:39:55.530 回答
0

如果您想通过套接字发送字符串,那么一个ObjectInputStreamObjectOutputStream不是正确的流实现。这些流实现使用 Java 对象序列化。即使您序列化String实例,生成的字节也与使用适当字符编码的纯字符串到字节转换不同。

而且 C# 应用程序根本不理解 Java 序列化。

考虑使用 aPrintWriter将字符串写入您的流并使用 aBufferedReader进行读取。

PrintWriter writer = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8"));
writer.println(...);


BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "UTF-8"));
String line = reader.readLine();

然后您可以逐行读取和写入字符串。这只是一个起点。如果你想实现自己的协议,你必须注意更多的点。例如,您可以阅读一些 TCP 协议(​​如POP3FTPHTTP 1.0 )的规范。

于 2012-05-29T21:50:38.923 回答