有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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()。 我猜这是因为服务器不知道消息应该在什么时候结束,但我不知道是否真的是这样,如果是这样,那么我如何修复它


共 (3) 个答案

  1. # 1 楼答案

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

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

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

  2. # 2 楼答案

    如果希望通过套接字发送字符串,那么ObjectInputStreamObjectOutputStream不是正确的流实现。这些流实现使用Java对象序列化。即使序列化String实例,得到的字节也不同于使用适当字符编码的普通字符串到字节的转换

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

    考虑使用^ {< CD4>}将字符串写入流,并使用^ {CD5>}进行读取。

    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

  3. # 3 楼答案

    InputStreamread()上没有更多可用数据时,这基本上就是导致EOF的原因。有多少数据是可用的由客户端决定的-它写入套接字OutputStream的数据在服务器端的InputStream套接字上显示为可用数据。您可以调用InputStream.available()来获得仍然是read()的字节数的估计值

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