0

TCP を使用して、クライアント/サーバー間で 12 個のオブジェクトを送受信したいと考えています。オブジェクトは一意ですが、順序は常に同じです。たとえば、クライアントは常に「オブジェクト 1」を送信して開始し、サーバーは常に「オブジェクト 2」で応答します。これを行うためにキューまたはスタックを設定し、Java 標準ライブラリのみを使用してオブジェクトの送受信を同期するにはどうすればよいですか? 以下のコード (1 つのパッケージから 3 つのクラス ファイル) に取り組みましたが、動作しません (ファイルの終わりエラー)。

import java.net.*;
import java.io.*;

class SimpleClient {
    public static void main(String args[]){
        int counter = 0;
        try{
            Socket s = new Socket("localhost",2002);
            OutputStream os = s.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(os);
            testobject to = new testobject(1,"object 1","field1","field2","field3","field4");
            System.out.println("sending object 1"); //debug
            oos.writeObject(to);
            //Socket ss = s.accept();
            InputStream is = s.getInputStream();
            ObjectInputStream ois = new ObjectInputStream(is);
            testobject too = (testobject)ois.readObject();
            while (counter != 2) {
                while ( too.value != 3 ) {
                    if (to==null) {
                        System.out.println("object is null!");
                    } else if (to.value==1){
                        System.out.println("receiving object 2"); //debug
                        System.out.println(to.id);
                        os = s.getOutputStream();
                        oos = new ObjectOutputStream(os);
                        testobject to0 = new testobject(2,"object 3","field1","field2","field3","field4");
                        oos.writeObject(to0);
                        System.out.println("object 3 sent!");
                    } else if (to.value==2){
                        System.out.println("receiving object 4"); //debug
                        System.out.println(to.id);
                        os = s.getOutputStream();
                        oos = new ObjectOutputStream(os);
                        testobject to0 = new testobject(3,"object 5","field1","field2","field3","field4");
                        oos.writeObject(to0);
                        System.out.println("sending object 5");
                    }
                }
                is.close();
                s.close();
                //System.out.println((String)ois.readObject());
                counter = counter + 1;
            }
            oos.close();
            os.close();
            s.close();
        } catch(Exception e) {
            System.out.println(e);
        }
    }
}

class SimpleServer {
    public static void main(String args[]) {
        int port = 2002;
        int counter = 0;
        try {
            ServerSocket ss = new ServerSocket(port);
            while (counter != 1) {
                Socket s = ss.accept();
                InputStream is = s.getInputStream();
                ObjectInputStream ois = new ObjectInputStream(is);
                testobject to = (testobject)ois.readObject();
                while ( to.value != 1 ) {
                    if (to==null) {
                        System.out.println("object is null!");
                    } else if (to.value==1){
                        System.out.println("receiving object 1"); //debug
                        System.out.println(to.id);
                        OutputStream os = s.getOutputStream();
                        ObjectOutputStream oos = new ObjectOutputStream(os);
                        testobject to0 = new testobject(2,"object 2","field1","field2","field3","field4");
                        oos.writeObject(to0);
                        System.out.println("sending object 2");
                    } else if (to.value==2){
                        System.out.println("receiving object 3"); //debug
                        System.out.println(to.id);
                        OutputStream os = s.getOutputStream();
                        ObjectOutputStream oos = new ObjectOutputStream(os);
                        testobject to0 = new testobject(4,"object 4","field1","field2","field3","field4");
                        oos.writeObject(to0);
                        System.out.println("sending object 4");
                    }
                }
                is.close();
                s.close();
                counter = counter + 1;
            }
            ss.close();
        } catch(Exception e) {
            System.out.println(e);
        }
    }
}

class testobject implements Serializable {
    int value;
    String id;
    String field1;
    String field2;
    String field3;
    String field4;
    public testobject(int v, String s, String s1, String s2, String s3, String s4) {
        this.value=v;
        this.id=s;
        this.field1 = s1;
        this.field2 = s2;
        this.field3 = s3;
        this.field4 = s4;
    }
}
4

1 に答える 1

1

コード内の EOFException

問題はあなたのようwhile (to.value != 1)です。サーバーは、値が 1 の最初のオブジェクトを受け取ります。その while ループはまったく実行されませんが、代わりにソケットがすぐに閉じられます。そのため、クライアントがそのソケットの入力ストリームから を作成しようとするObjectInputStreamと、オブジェクト ストリーム ヘッダーが必要な場所で閉じられた接続が発生します。したがって、EOFException.

会話の実装

会話を実装する最も簡単な方法は、ループを完全に回避することです。結局のところ、ループを実行しますが、ループ内で大文字と小文字を区別して、各パスで特別なコードを実行します。線形プログラムを作成し、必要に応じて一般的なコードをメソッド呼び出しに分解することもできますが、この例には一般的なコードはほとんどありません。

class SimpleClient {
    public static void main(String args[]) throws Exception {

        // Connection setup
        Socket s = new Socket("localhost",2002);
        OutputStream os = s.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        InputStream is = s.getInputStream();
        ObjectInputStream ois = new ObjectInputStream(is);
        testobject to;

        // Conversation

        System.out.println("sending object 1");
        to = new testobject(1,"object 1","field1","field2","field3","field4");
        oos.writeObject(to);

        System.out.println("receiving object 2");
        to = (testobject)ois.readObject();
        System.out.println(to.id);

        System.out.println("sending object 3");
        to = new testobject(2,"object 3","field1","field2","field3","field4");
        oos.writeObject(to);

        System.out.println("receiving object 4");
        to = (testobject)ois.readObject();
        System.out.println(to.id);

        // Connection shutdown
        ois.close();
        oos.close();
        s.close();
    }
}

class SimpleServer {
    public static void main(String args[]) throws Exception {

        // Connection setup
        ServerSocket ss = new ServerSocket(2002);
        Socket s = ss.accept(); // only handle a single connection
        ss.close(); // so we can immediately stop listening for more
        OutputStream os = s.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        InputStream is = s.getInputStream();
        ObjectInputStream ois = new ObjectInputStream(is);
        testobject to;

        // Conversation

        System.out.println("receiving object 1");
        to = (testobject)ois.readObject();
        System.out.println(to.id);

        System.out.println("sending object 2");
        to = new testobject(2,"object 2","field1","field2","field3","field4");
        oos.writeObject(to);

        System.out.println("receiving object 3");
        to = (testobject)ois.readObject();
        System.out.println(to.id);

        System.out.println("sending object 4");
        to = new testobject(4,"object 4","field1","field2","field3","field4");
        oos.writeObject(to);

        // Connection shutdown
        ois.close();
        oos.close();
        s.close();
    }
}

送受信キュー

本当にキューから何かを送信したい場合は、単純にそれを繰り返すことができます。

import java.net.*;
import java.io.*;
import java.util.*;

class SimpleClient {
    public static void main(String args[]) throws Exception {

        // Preparing the queues
        List<testobject> sendQueue = Arrays.asList(
            new testobject(1,"object 1","field1","field2","field3","field4"),
            new testobject(2,"object 3","field1","field2","field3","field4"));
        List<testobject> receiveQueue = new ArrayList<testobject>();

        // Connection setup
        Socket s = new Socket("localhost",2002);
        OutputStream os = s.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        InputStream is = s.getInputStream();
        ObjectInputStream ois = new ObjectInputStream(is);
        testobject to;

        // Conversation, we start by sending
        for (testobject toSend: sendQueue) {
            System.out.println("Sending " + toSend.id);
            oos.writeObject(toSend);
            testobject received = (testobject)ois.readObject();
            System.out.println("Received " + received.id);
            receiveQueue.add(received);
        }

        // Connection shutdown
        ois.close();
        oos.close();
        s.close();
    }
}

class SimpleServer {
    public static void main(String args[]) throws Exception {

        // Preparing the queues
        List<testobject> sendQueue = Arrays.asList(
            new testobject(2,"object 2","field1","field2","field3","field4"),
            new testobject(4,"object 4","field1","field2","field3","field4"));
        List<testobject> receiveQueue = new ArrayList<testobject>();

        // Connection setup
        ServerSocket ss = new ServerSocket(2002);
        Socket s = ss.accept(); // only handle a single connection
        ss.close(); // so we can immediately stop listening for more
        OutputStream os = s.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        InputStream is = s.getInputStream();
        ObjectInputStream ois = new ObjectInputStream(is);
        testobject to;

        // Conversation, we start by receiving
        for (testobject toSend: sendQueue) {
            testobject received = (testobject)ois.readObject();
            System.out.println("Received " + received.id);
            receiveQueue.add(received);
            System.out.println("Sending " + toSend.id);
            oos.writeObject(toSend);
        }

        // Connection shutdown
        ois.close();
        oos.close();
        s.close();
    }
}

ただし、この場合、すべてのデータが事前にわかっているため、物事をインターリーブするのではなく、別のスレッドを使用して物事を受信する代わりに、両端ですべてのデータをすぐに送信することで、ネットワークの往復を節約できます。ただし、それはあなたの例からさらに離れているため、このコードは含めません。

于 2013-10-01T07:35:27.223 に答える