11
public class SerProg {


    static ServerSocket ser=null;
    static Socket cli=null;
    static ObjectInputStream ins=null;
    static ObjectOutputStream outs=null;


    public static void main(String[] args) {

        try {

            ser=new ServerSocket(9000,10);
            cli=ser.accept();

            System.out.println("Connected to :"+cli.getInetAddress().getHostAddress()+" At Port :"+cli.getLocalPort());

            ins=new ObjectInputStream(cli.getInputStream());
            outs=new ObjectOutputStream(cli.getOutputStream());

            String str=(String)ins.readObject();


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

そしてクライアント

public class SerProg {

    /**
     * @param args
     */
    static ServerSocket ser=null;
    static Socket cli=null;
    static ObjectInputStream ins=null;
    static ObjectOutputStream outs=null;


    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try {

            ser=new ServerSocket(9000,10);
            cli=ser.accept();

            System.out.println("Connected to :"+cli.getInetAddress().getHostAddress()+" At Port :"+cli.getLocalPort());

            ins=new ObjectInputStream(cli.getInputStream());
            outs=new ObjectOutputStream(cli.getOutputStream());

            String str=(String)ins.readObject();


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

接続は正常に確立されましたが、サーバーコード行にあります

ins=new ObjectInputStream(cli.getInputStream());

コードが停止して続行しない場合、何が問題になる可能性がありますか?

4

2 に答える 2

37

接続の両側でObjectOutputStream前を作成する必要があります(!)。ObjectInputStreamObjectInputStream作成されると、からオブジェクトストリームヘッダーを読み取ろうとしますInputStream。したがってObjectOutputStream、反対側がまだ作成されていない場合、読み取るオブジェクトストリームヘッダーがなく、無期限にブロックされます。

または別の言い方をすると、両方が最初にを作成する場合ObjectInputStream、両方がオブジェクトストリームヘッダーの読み取りをブロックします。オブジェクトストリームヘッダーは、ObjectOutputStream(行の反対側に)作成されるまで書き込まれません。のコンストラクターで両側がブロックされているため、これは発生しませんObjectInputStream

これは、次のJavadocから推測できますObjectInputStream(InputStream in)

シリアル化ストリームヘッダーがストリームから読み取られ、検証されます。このコンストラクターは、対応するObjectOutputStreamがヘッダーを書き込んでフラッシュするまで、ブロックします。

これは、EsmondPittによるJavaの基本的なネットワーキングのセクション3.6.2でも説明されています。

于 2013-01-01T13:53:42.187 に答える
-1

ストリームのハンドシェイクを行う必要があります。つまり、クライアント側では、オブジェクト入力ストリームを作成するときに、サーバー側でオブジェクト出力ストリームを作成する必要があります。

//SERVER SIDE
Socket clientSocket = TcpServer.socket.accept();
// 1. input stream;
ObjectInputStream sInput = new ObjectInputStream(clientSocket.getInputStream());
// 2. output stream
ObjectOutputStream sOutput = new ObjectOutputStream(clientSocket.getOutputStream());


//CLIENT SIDE
Socket socket = new Socket(ip, port);
// 2. output stream
ObjectOutputStream sOutput = new (socket.getOutputStream());
// 1. input stream
ObjectInputStream sInput = new ObjectInputStream(socket.getInputStream());

ストリームのハンドシェイクを作成する方法を示してみました。

于 2020-02-23T10:59:06.343 に答える