在Java中向服务器发送不同的对象

在Java中向服务器发送不同的对象,java,tcp,client-server,inputstream,Java,Tcp,Client Server,Inputstream,我有几节课。 学生、老师和书本 我想将这3个对象的实例从服务器发送到连接的客户端。 我知道如何使用以下代码发送/接收单一类型的实例,即学生从服务器到客户端 客户端 Socket socket = new Socket(ip, port); try { ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream());

我有几节课。 学生、老师和书本

我想将这3个对象的实例从服务器发送到连接的客户端。 我知道如何使用以下代码发送/接收单一类型的实例,即学生从服务器到客户端

客户端

            Socket socket = new Socket(ip, port);
        try {
            ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream());
            try {
                Object object =(Student) objectInput.readObject();
                Student std = (Student) object;
                //do something with std
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }          
服务器端

        Student a = new Student();
        ServerSocket myServerSocket = new ServerSocket(port);
        Socket skt = myServerSocket.accept();   
        try 
        {
            ObjectOutputStream objectOutput = new ObjectOutputStream(skt.getOutputStream());
            objectOutput.writeObject(a);                
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        } 
如何扩展此代码,以便能够从服务器发送不同类型的对象,并在客户端正确接收它们

我是否需要将它们全部包装在另一个对象中,并为每个对象指定一个类型? 谢谢

我是否需要将它们全部包装在另一个对象中,并为每个对象指定一个类型

  • 创建一个将聚合所有对象实例的类可能是更好的设计。这将防止错误,并产生更可读的代码

  • 如果您只想在客户机和服务器之间交换普通java对象,最好使用(本文中包括的示例)之类的方法

  • 如何扩展此代码以能够发送不同类型的对象 从服务器

    如果您坚持学习套接字,您可以一个接一个地发送和接收对象实例

    您还可以发送对象数组

    客户示例:

    public class Client {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("127.0.0.1", 6060);
    
            try {
                ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream());
                Student student = (Student)objectInput.readObject();
    
                System.out.println("Received student (" + student + ")");
    
                objectInput = new ObjectInputStream(socket.getInputStream());
                Teacher teacher  = (Teacher) objectInput.readObject();
    
                System.out.println("Received teacher (" + teacher + ")");
    
                //do something with std
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }  finally {
                socket.close();
            }
        }
    }
    
    服务器示例:

    public class Server {
        public static void main(String[] args) throws IOException {
            ServerSocket myServerSocket = new ServerSocket(6060);
            System.out.println("Up and running");
            Socket skt = myServerSocket.accept();   
            try {
                Student student = new Student();
                ObjectOutputStream objectOutput = new ObjectOutputStream(skt.getOutputStream());
                objectOutput.writeObject(student);
                System.out.println("Sent student");
    
                Teacher teacher = new Teacher();
                objectOutput = new ObjectOutputStream(skt.getOutputStream());
                objectOutput.writeObject(teacher);
                System.out.println("Sent teacher");
            } 
            catch (IOException e) {
                e.printStackTrace();
            } finally {
                myServerSocket.close();
            }
    
            System.out.println("Shutting down");
        }
    }
    

    但是这种方法很难理解,而且容易出现错误,因为如果在
    客户端和
    服务器上都没有正确的顺序,那么这个代码就不起作用了。

    正如我理解的问题,您想知道如何检测发送给您的对象的类型 我怀疑instanceof和类似的方法会起作用

    也可以使用封套将对象包裹在其中。这与此基本相同,但可能允许您在其中包含错误标志、路由信息和紧急标志

    public static class Envelope implements Serializable {
        private final Object contents;
        private final String type;
    
        public Envelope(final Object contents, String type) {
            this.contents = contents;
            this.type = type;
        }
    
        public <T> T getContents(Class<T> clazz) {
            return (T) contents;
        }
    
        public String getType() {
            return type;
        }
    }
    
    public static void main(String[] argv) {
    
        Envelope stringEnvelope = new Envelope("abcd", "String");
    
        PipedInputStream reader = new PipedInputStream();
        PipedOutputStream writer = new PipedOutputStream();
    
        try {
            reader.connect(writer);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(writer);
            ObjectInputStream objectInputStream = new ObjectInputStream(reader);
    
            objectOutputStream.writeObject(stringEnvelope);
    
            Envelope envelope = (Envelope) objectInputStream.readObject();
            String type = envelope.getType();
            if (type.equals("String")) {
                String result = envelope.getContents(String.class);
                System.out.println(result);
            }
        } catch (ClassNotFoundException c) {
    
        } catch (IOException e) {
    
        }
    
    }
    
    公共静态类信封实现可序列化{
    私人最终客体内容;
    私有最终字符串类型;
    公共信封(最终对象内容,字符串类型){
    this.contents=目录;
    this.type=type;
    }
    公共课内容(课堂){
    返回(T)内容;
    }
    公共字符串getType(){
    返回类型;
    }
    }
    公共静态void main(字符串[]argv){
    信封字符串信封=新信封(“abcd”,“字符串”);
    PipedInputStream读取器=新的PipedInputStream();
    PipedOutputStream writer=new PipedOutputStream();
    试一试{
    读卡器。连接(写卡器);
    ObjectOutputStream ObjectOutputStream=新的ObjectOutputStream(编写器);
    ObjectInputStream ObjectInputStream=新ObjectInputStream(读卡器);
    objectOutputStream.writeObject(stringEnvelope);
    信封信封=(信封)objectInputStream.readObject();
    字符串类型=envelope.getType();
    if(type.equals(“字符串”)){
    字符串结果=envelope.getContents(String.class);
    系统输出打印项次(结果);
    }
    }捕获(ClassNotFoundException c){
    }捕获(IOE异常){
    }
    }
    
    您可以将对象包装到新类中:

    public class ObjectMessage{
        public objecttype;
        public Object payload;
        public ObjectMessage(int objt, Object pay){
            objecttype=objt;
            payload=pay;
        }
    }
    
    当然,您还需要更改客户端:

    Socket socket = new Socket(ip, port);
    try {
        ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream());
        try {
            Object object = objectInput.readObject();
            ObjectMessage msg = (ObjectMessage) object;
            if(msg.objecttype == 0){
                Student std = (Student) msg.payload;
                //do something with std
            }else if(msg.objecttype == 1){
                //do something with Teacher, Book or whatever
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }      
    
    服务器现在执行以下操作:

    Student a = new Student(); //or Teacher, Book etc.
    ObjectMessage message = new ObjectMessage(0,a); //use other numbers for other objects
    ServerSocket myServerSocket = new ServerSocket(port);
    Socket skt = myServerSocket.accept();   
    try 
    {
        ObjectOutputStream objectOutput = new ObjectOutputStream(skt.getOutputStream());
        objectOutput.writeObject(message);                
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    } 
    

    (您可能还想看看序列化:)

    impment Serializable