我认为这是因为当我多线程化客户端和服务器时,我使用的DataOutputStream
和DataInputStream
缓冲区会被覆盖或类似的东西,因为套接字只能有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并允许自己执行多线程客户端 - 服务器套接字交互?
(最好不要改变我的代码,因为我花了很长时间才达到这一点)。
答案 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();
}
}
}