Java套接字 - 尝试实现多线程时的EOFException

时间:2015-10-22 08:52:25

标签: java multithreading sockets client-server eofexception

我认为这是因为当我多线程化客户端和服务器时,我使用的DataOutputStreamDataInputStream缓冲区会被覆盖或类似的东西,因为套接字只能有1个双工连接。

这就是我现在所拥有的:

我的客户端程序中的客户端类:

public static void main(String args[]) throws UnknownHostException, IOException, InterruptedException {
        for (int i=0;i<2;i++) //change limit on i to change number of threads
        {
            new Thread(new ClientHandler(i)).start();
        }
        Thread.sleep(10000);

我的客户端程序中的ClientHandler类: (向服务器发送一个值,服务器将回显它)。

public class ClientHandler implements Runnable {
public int clientNumber;
public ClientHandler(int i){
    this.clientNumber=i;
}
public void run() {
        Socket socket = null;
        try {
            socket = new Socket("localhost",9990);
            System.out.println("connected client number "+clientNumber);
            DataOutputStream output = new DataOutputStream(socket.getOutputStream());
            DataInputStream input = new   DataInputStream(socket.getInputStream());
            output.writeDouble((new Random()).nextDouble());
            System.out.println(input.readDouble());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

我的服务器程序中的服务器类:

    ServerSocket socket = new ServerSocket(9990);
    try { 
        while (true) {
            Socket threadSocket = socket.accept();
            new Thread(new ServerHandler(threadSocket)).start();
            Thread.sleep(10000);
}
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    finally {
        socket.close();
        }
    }
}

我的服务器程序中的ServerHandler类(从客户端接收值并回送它)

public class ServerHandler implements Runnable {
    private Socket socket;
    public ServerHandler(Socket socket) {
    this.socket = socket;
}

public void run() {
    while(true) {
      try {
            DataInputStream input = new DataInputStream(socket.getInputStream());
            DataOutputStream output = new DataOutputStream(socket.getOutputStream());
    double a = input.readDouble();
            output.writeDouble(a);

}catch (IOException e){
      e.printStackTrace();

  }
}

}

所以这是一个非常简单的实现:创建客户端的多个线程,并将它们连接到服务器的多个线程。

一切正常,直到这一行:

double a = input.readDouble();

在我的ServerHandler类中。

我得到EOFException

我猜是因为套接字之间只能有一个双工连接。但如果是这样的话,我将如何实现套接字的多线程?

所以我的问题是:如何摆脱EOFException并允许自己执行多线程客户端 - 服务器套接字交互?

(最好不要改变我的代码,因为我花了很长时间才达到这一点)。

1 个答案:

答案 0 :(得分:1)

问题是您在 ServerHandler 中为所有线程共享相同的 Socket 变量:

private static Socket socket

删除静态关键字。您的ServerHandler将是这样的:

public static class ServerHandler implements Runnable {
    private Socket socket;

    public ServerHandler(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            DataInputStream input = new DataInputStream(socket.getInputStream());
            DataOutputStream output = new DataOutputStream(socket.getOutputStream());
            double a = input.readDouble();
            output.writeDouble(a);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}