如何在java中通过TCP发送OBJECT?

时间:2012-10-16 08:20:36

标签: java sockets serialization tcp connection

我正在编写一个程序,将对象从一个类发送到另一个类。这是我的程序的一个简短示例,用于表示问题。正如您所看到的,从服务器发送到客户端的对象是Student类,它已在每个类(服务器/客户端)中单独定义。我通过发送一个工作正常的ArrayList来检查此代码,但是当它来自我自己定义的类类型我收到此错误:

Exception in thread "main" java.lang.ClassCastException: ServerSide$1Student cannot be cast to ClientSide$1Student
    at ClientSide.main(ClientSide.java:29)

以下是服务器端的代码:

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

public class ServerSide {

    public static void main(String[] args) {
        class Student implements Serializable
        {
            int id;
            public Student(int num){id=num;}
            public void setID(int num){id=num;}
            public void Print(){System.out.println("id = " + id);}
        }
        try
        {
            Student a = new Student(3);
            ServerSocket myServerSocket = new ServerSocket(9999);
            Socket skt = myServerSocket.accept();   
            try 
            {
                ObjectOutputStream objectOutput = new ObjectOutputStream(skt.getOutputStream());
                objectOutput.writeObject(a);                
            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            } 
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
}

对于客户端来说是:

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientSide {

    public static void main(String[] args)
    {
        class Student implements Serializable
        {
            int id;
            public Student(int num){id=num;}        
            public void setID(int num){id=num;}
            public void Print(){System.out.println("id = " + id);}
        }
        try {       
            Socket socket = new Socket("10.1.1.2",9999);
            try {
                ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream());
                try {
                    Object object =(Student) objectInput.readObject();
                    Student tmp = (Student) object;
                    tmp.Print();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }           
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }   
    }   
}

修改

我将它们移动到同一个文件并添加了序列号ID。它工作正常。

3 个答案:

答案 0 :(得分:12)

拥有两个同名的课程是不够的。这两个类需要

  • 同一个包
  • 如果有任何
  • ,则在同一外层
  • 具有相同的serialVersionUID。

我建议你有一个单独的类,这对于客户端和服务器都是常见的。在更复杂的项目中,您可以考虑在客户端和服务器模块都依赖的模块中构建这些公共组件。

答案 1 :(得分:4)

您不能将表示类X实例的流反序列化为类Y的实例。

要解决您的问题,您需要将Student类的代码移动到另一个文件,例如Student.java,并在客户端代码和服务器代码上使用该单个类。

请注意,如果修改类,在大多数情况下,您将需要重新部署服务器(否则客户端会向服务器发送一个流,该流表示仅为客户端所知的类实例)。

答案 2 :(得分:2)

您正在引用两个不同的类。 StudentClientSideStudent的内部,ServerSideStudent的内部类。您应该将{{1}}类移动到其他文件。