我创建了一个基于服务器的聊天程序,该程序有多个工作线程,每个线程处理套接字上的客户端。它有一个服务器套接字将客户端传递给工作线程。Java使用客户端套接字的多个线程
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4001);
System.out.println("Listening server");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("Connected");
Random rand= new Random();
int port=4001+rand.nextInt(5);
Worker worker = new Worker(port);
executor.execute(worker);
System.out.println("Thread started");
new PrintWriter(socket.getOutputStream(), true).println(port);
socket.close();
System.out.println("Closed");
// break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public class Worker implements Runnable {
private int port;
public Worker(int i) {
port=i;
}
@Override
public void run() {
worker();
}
private static Socket socket;
private static PrintWriter out;
private static BufferedReader in;
private void worker() {
try {
ServerSocket serverSocket = new ServerSocket(port);
socket = serverSocket.accept();
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println("Received: " + line);
switch (line) {
case ("Button Press"):
System.out.println("Handled button");
out.println("Button acknowledged");
break;
case ("Give me some data"):
System.out.println("Handled data");
out.println("Have some data");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这工作得很好,然而,问题是当我有由客户端的自动请求来检查消息和用户提供的相同类型的某些输入。这会导致冲突,因为实际方法需要运行几秒钟,并且如果接收到更多输入,则请求将不会被处理,因为它位于方法的中间。例如:
private static BufferedReader in;
private static PrintWriter out;
public static void main(String[] args) {
Main main=new Main();
main.createWindow();
try {
Socket init = new Socket(InetAddress.getLocalHost(), 4001);
int port
=Integer.parseInt
(new BufferedReader
(new InputStreamReader(init.getInputStream())).readLine());
init.close();
Socket socket=new Socket(InetAddress.getLocalHost(), port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
try {
Thread.sleep(5000);
out.println("Give me some data");
if(in.readLine().equals("Have some data")){
System.out.println("Data recieved");
}else{
System.out.println("Data not recieved");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void createWindow(){
JFrame frame =new JFrame("This is a button");
Container pane=getContentPane();
JButton button=new JButton("This is a button");
button.addActionListener(this);
pane.add(button);
frame.setTitle("Messaging");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(pane);
frame.setVisible(true);
frame.setSize(400, 350);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button press");
try {
out.println("Button Press");
if(in.readLine().equals("Button acknowledged")){
System.out.println("Button complete");
}else{
System.out.println("Button fail");
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
如果按钮被按下,而服务器获取数据它冲突和错误的响应发送。那么我会如何处理这个问题呢?如果我创建一个单独的套接字来处理自动检查,这是服务器必须处理的线程数量的两倍。有更好的解决方案吗? 请你可以尝试解释,因为这对我来说是一个新的领域。
你的第一个问题是这些变量都不应该是静态的,而那些指向特定客户端的变量应该在'Worker'类中,而不是服务器类中。 – EJP
是的服务器工人类中的变量可能不应该是静态的,但这是因为这是我在5分钟内扔在一起的东西,以提供我的问题的一个例子。 而引用特定客户端的变量不在工作者类中,就我所见,它只是服务器套接字,最初的套接字和线程池。那么哪些不是在那里?但正如我已经说过的那样,这只是一些快速拼凑在一起的代码,试图帮助解决我的问题,所以它不会是完美的。 – Nightfortress