Java 客户机-服务器程序的多线程处理
我正在尝试用我一直在开发的客户机/服务器程序实现多线程。我需要允许多个客户端同时连接到服务器。我目前有4个类:一个客户端、一个服务器、一个协议和一个工作线程。以下代码是这些类的代码: SocketServer类:Java 客户机-服务器程序的多线程处理,java,multithreading,sockets,client-server,Java,Multithreading,Sockets,Client Server,我正在尝试用我一直在开发的客户机/服务器程序实现多线程。我需要允许多个客户端同时连接到服务器。我目前有4个类:一个客户端、一个服务器、一个协议和一个工作线程。以下代码是这些类的代码: SocketServer类: public class SocketServer { public static void main(String[] args) throws IOException { int portNumber = 9987; try (
public class SocketServer {
public static void main(String[] args) throws IOException {
int portNumber = 9987;
try (
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {
Thread thread = new Thread(new ClientWorker(clientSocket));
thread.start(); //start thread
String inputLine, outputLine;
// Initiate conversation with client
Protocol prot = new Protocol();
outputLine = prot.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = prot.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("quit"))
break;
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
SocketClient类:
public class SocketClient {
public static void main(String[] args) throws IOException
{
String hostName = "localhost";
int portNumber = 9987;
try (
Socket socket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
) {
BufferedReader stdIn =
new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("quit"))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
hostName);
System.exit(1);
}
}
}
协议类别:
public class Protocol {
private static final int waiting = 0;
private static final int sentPrompt = 1;
private int status = waiting;
public String processInput(String theInput) {
String theOutput = null;
if (status == waiting) {
theOutput = "Please enter what you would like to retrieve: 'customer' or 'product' ";
status = sentPrompt;
}
else if ( status == sentPrompt ) {
if ( theInput.equalsIgnoreCase("product")) {
File f = new File("product.txt");
Scanner sc = null;
try {
sc = new Scanner(f);
} catch (FileNotFoundException ex) {
Logger.getLogger(Protocol.class.getName()).log(Level.SEVERE, null, ex);
}
while ( sc.hasNextLine() ) {
String line = sc.nextLine();
theOutput = "The current product entries are : " + line;
}
return theOutput;
}
else if ( theInput.equalsIgnoreCase("customer")) {
File f = new File("customer.txt");
Scanner sc = null;
try {
sc = new Scanner(f);
} catch (FileNotFoundException ex) {
Logger.getLogger(Protocol.class.getName()).log(Level.SEVERE, null, ex);
}
while ( sc.hasNextLine() ) {
String line = sc.nextLine();
theOutput = "The current customer entries are : " + line;
}
return theOutput;
}
else if ( theInput.equalsIgnoreCase("quit")) {
return "quit";
}
else {
return "quit";
}
}
return theOutput;
}
}
ClientWorker类:
public class ClientWorker implements Runnable {
private final Socket client;
public ClientWorker( Socket client ) {
this.client = client;
}
@Override
public void run() {
String line;
BufferedReader in = null;
PrintWriter out = null;
try {
System.out.println("Thread started with name:"+Thread.currentThread().getName());
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("in or out failed");
System.exit(-1);
}
while (true) {
try {
System.out.println("Thread running with name:"+Thread.currentThread().getName());
line = in.readLine();
//Send data back to client
out.println(line);
//Append data to text area
} catch (IOException e) {
System.out.println("Read failed");
System.exit(-1);
}
}
}
}
当我运行服务器和客户端时,一切正常。然后,当我尝试运行另一个客户机时,它只是挂在那里,不会提示客户机给出响应。非常感谢您对我所缺少的任何见解 调用了多少次
serverSocket.accept()
?
一旦
这就是它将处理的客户数量。
试图联系的后续客户将不会有任何人接听
要处理更多客户端,您需要在循环中调用
serverSocket.accept()
。调用serverSocket.accept()
多少次?
一旦
这就是它将处理的客户数量。
试图联系的后续客户将不会有任何人接听
要处理更多客户端,您需要在循环中调用
serverSocket.accept()
。您的服务器代码应该实现以下功能
ClientWorker
ServerSocket serverSocket = new ServerSocket(portNumber);
while(true){
try{
Socket clientSocket = serverSocket.accept();
Thread thread = new ClientWorker(clientSocket);
thread.start(); //start thread
}catch(Exception err){
err.printStackTrace();
}
}
您的服务器代码应该解决实现以下功能的问题
ClientWorker
ServerSocket serverSocket = new ServerSocket(portNumber);
while(true){
try{
Socket clientSocket = serverSocket.accept();
Thread thread = new ClientWorker(clientSocket);
thread.start(); //start thread
}catch(Exception err){
err.printStackTrace();
}
}
你的程序具体挂在哪里?我猜在ServerSocket的while循环中。@hotzst:是的。我对使用其他方法持开放态度,我也一直在研究线程池。但是我需要在每一个线程中使用这个协议。代码质量的旁注:这个代码几乎是可怕的“不干净”。例如,我衷心建议从Robert Martin开始编写“干净的代码”,以了解您可以通过多少方式改进源代码。@Jägermeister:注意。好的,谢谢。你的程序具体挂在哪里?我猜在ServerSocket的while循环中。@hotzst:是的。我对使用其他方法持开放态度,我也一直在研究线程池。但是我需要在每一个线程中使用这个协议。代码质量的旁注:这个代码几乎是可怕的“不干净”。例如,我衷心建议从Robert Martin开始编写“干净的代码”,以了解您可以通过多少方式改进源代码。@Jägermeister:注意。好的,谢谢。谢谢!我是保留协议proceInput的try/catch还是将其移动到ClientWorker run()方法?try{}catch{}中的ClientWorker应该很好谢谢!我是保留协议proceInput的try/catch还是将其移动到ClientWorker run()方法?try{}catch{}中的ClientWorker应该可以