在Java中使用Socket时转换为接口

时间:2017-05-24 09:39:59

标签: java sockets serialization interface

我遇到了一个非常难以理解的问题。所以我创建了两个不同的项目,并决定测试我试图通过网络发送接口的套接字应用程序。这是我的客户端代码:

package calculable;

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

public class ClientToSendCalculable
{
    public ClientToSendCalculable(int port)
    {
        try
        (
            Socket s = new Socket("localhost", port);
            ObjectOutputStream writer = new ObjectOutputStream(s.getOutputStream());
            ObjectInputStream reader = new ObjectInputStream(s.getInputStream());
        )
        {
            System.out.println("Connection was established!");

            Calculable addition = new Addition(5, 7);

            writer.writeObject(addition);
            double res = (Double)reader.readObject();

            System.out.println(res);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String[] args)
    {
        new ClientToSendCalculable(7777);
    }
}

这是我的服务器端代码:

package calculable;

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

public class ServerToGetCalculable
{
    public ServerToGetCalculable(int port)
    {
        while(true)
        {
            try
                    (
                            ServerSocket ss = new ServerSocket(port);
                            Socket s = ss.accept();
                            ObjectOutputStream writer = new ObjectOutputStream(s.getOutputStream());
                            ObjectInputStream reader = new ObjectInputStream(s.getInputStream());
                    )
            {
                System.out.println("Got a client!");

                Calculable calcObj = (Calculable) reader.readObject();
                double res = calcObj.calc();
                writer.writeObject(res);
            }catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args)
    {new ServerToGetCalculable(7777);}
}

这是接口可计算:

package calculable;

import java.io.Serializable;

public interface Calculable extends Serializable
{
    double calc();
}

我在两个项目中都有可计算的界面。但我只在客户端项目中有Addition类。这是Addition类:

package calculable;

import java.io.Serializable;

public class Addition implements Calculable, Serializable
{
    private double firstAddendum, secondAddendum;

    public Addition(double firstAddendum, double secondAddendum)
    {
        this.firstAddendum = firstAddendum;
        this.secondAddendum = secondAddendum;
    }

    public double calc()
    {
        return firstAddendum + secondAddendum;
    }
}

当我得到这样的例外后,首先启动server.main class和client.main类:

服务器端的

异常:

"C:\Program Files\Java\jdk1.8.0_91\bin\java" -Didea.launcher.port=7544 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_91\jre\lib\charsets.jar;C:\Program .....E:\Cloud\JavaIdea\ForCalculablePractice\out\production\ForCalculablePractice;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.3.3\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain calculable.ServerToGetCalculable
Got a client!
java.lang.ClassNotFoundException: calculable.Addition
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:628)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
    at calculable.ServerToGetCalculable.<init>(ServerToGetCalculable.java:24)
    at calculable.ServerToGetCalculable.main(ServerToGetCalculable.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

客户端的例外:

"C:\Program Files\Java\jdk1.8.0_91\bin\java" -Didea.launcher.port=7545 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_91\jre\lib\charsets.jar;.....E:\Cloud\JavaIdea\SocketPractice\out\production\SocketPractice;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.3.3\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain calculable.ClientToSendCalculable
Connection was established!
java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
    at calculable.ClientToSendCalculable.<init>(ClientToSendCalculable.java:22)
    at calculable.ClientToSendCalculable.main(ClientToSendCalculable.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Process finished with exit code 0

2 个答案:

答案 0 :(得分:1)

发送接口 - 这是你的错误观念。事实上你放下了:

Calculable addition = new Addition(5, 7);

并不代表你设置了一个&#34;界面&#34;电线上的物体。

您发送序列化对象。该对象包含特定类的链接。有关详细信息,请参阅here

您无法在代码中解决此问题。您必须确保序列化对象的**类*可用于要进行反序列化的JVM。就这么简单。

答案 1 :(得分:1)

您正在发送服务器不知道的对象。您需要将additions对象的类文件(包括AdditionCalculable)添加到服务器的类路径(如果使用IDE,则添加到您的项目中)。