带套接字的 ObjectStreams 在服务器端和客户端挂起 java

ObjectStreams with sockets hang at server and client side java

我有这个代码:

package com.company;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;

class MyClass implements Serializable
{
    private int i,j;

    public MyClass(int i, int j)
    {
        this.i = i;
        this.j = j;
    }

    public int getJ()
    {
        return j;
    }

    public void setJ(int j)
    {
        this.j = j;
    }

    public int getI()
    {
        return i;
    }

    public void setI(int i)
    {
        this.i = i;
    }
}
class ServerThread extends Thread
{
    ServerSocket server;

    public ServerThread() throws IOException
    {
        server=new ServerSocket(14200);
    }

    @Override
    public void run()
    {
        try
        {
            Socket client=server.accept();
            ObjectInputStream in=new ObjectInputStream(client.getInputStream());
            ObjectOutputStream out=new ObjectOutputStream(client.getOutputStream());
            int i=in.readInt();
            MyClass m=(MyClass)in.readObject();
            if(i==m.getI())
            {
                m.setJ(i);
                out.writeObject(m);
            }
            else
            {
                m.setI(i);
                out.writeObject(m);
            }
            out.writeUTF("see ya");
        }
        catch (IOException | ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}
public class Main
{
    public static void main(String... args) throws IOException, ClassNotFoundException
    {
        ServerThread serverThread=new ServerThread();
        serverThread.setDaemon(true);
        serverThread.start();
        Socket client=new Socket("localhost",14200);
        ObjectInputStream in=new ObjectInputStream(client.getInputStream());
        ObjectOutputStream out=new ObjectOutputStream(client.getOutputStream());
        out.writeInt(2);
        out.writeObject(new MyClass(4,2));
        MyClass m=(MyClass)in.readObject();
        String s=in.readUTF();
        System.out.println(s);
    }
}

我的问题是客户端和服务器都挂在这条线上:

ObjectInputStream in=new ObjectInputStream(client.getInputStream);  

如果我为套接字设置超时,我会得到 SocketTimeoutException。

真实目标

上面的程序只是一个虚拟程序,但显示了我的问题,真正的程序是一个用于共享文件的服务器-客户端应用程序,我在其中实现了自己的简单协议,这实际上是一个家庭作业。

我们被要求实现数字签名,我创建了自己的助手 classes,最后我得到了 SignatureWithPublicKey class(由我定义),它包含签名字节和 public 键,我需要通过套接字发送这个对象。

一个简单的解决方案是将 PublicKey.getEncoded 与签名字节一起发送但是我想使用 ObjectStreams,我需要知道它们为什么不工作。

那么这里的问题是什么?

Object 流有一个小 header。这意味着在发送和读取 header 之前,您甚至无法启动 object 输入流。但是,在您调用 ObjectOutputStream 之前,您的代码不会发送 header,在这种情况下,您是在输入流之后执行的。即你有一个死锁。

简而言之,在这两种情况下交换 new ObjectInputStreamnew ObjectOutputStream 的顺序。