多线程聊天服务器 [英] Multi threaded chat server

查看:123
本文介绍了多线程聊天服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Threads的新手。我试图从服务器向客户端广播消息。但我不能。看起来服务器总是监听新的连接。但我可以使用客户端终端向其他客户端发送消息。我的问题是如何在同时收听时允许输入。这是代码。

I am new to Threads. I am trying to broadcast message from the server to clients.but I cannot. It seems like the server is always listen to a new connection.But I can send messages to other clients using the clients terminal. My question is how to allow input while listening at the same time. Here is the code.

MultiThreadChatServerSync.java

MultiThreadChatServerSync.java

import java.io.InputStreamReader;
import java.io.DataInputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.BufferedReader;

public class MultiThreadChatServerSync extends Thread {

   private static ServerSocket serverSocket = null;
   private static Socket clientSocket = null;
   private static Socket serversSocket = null;
   private static DataInputStream iss = null;
   private static PrintStream oss = null;

   private static final int maxClientsCount = 10;
   private static final clientThread[] threads = new clientThread[maxClientsCount];

   public static void main(String args[]) {
      int num = 0;
      int portNumber = 2222;
      if (args.length < 1) {
         System.out.println("Usage: java MultiThreadChatServerSync<portNumber> "Nowusingnumber=" + portNumber);
      } else {
         portNumber = Integer.valueOf(args[0]).intValue();
      }
      try {
         serverSocket = new ServerSocket(portNumber);
      } catch (IOException e) {
         System.out.println(e);
      }
      DataInputStream iss = null;
      while (true) {
         try {
            System.out.println("5");

            num++;

            // I want to be able to input text here to the server which will be
            // send to different clients
            // But I cannot

            clientSocket = serverSocket.accept();
            int i = 0;
            for (i = 0; i < maxClientsCount; i++) {
               if (threads[i] == null) {
                  System.out.println("6");
                  (threads[i] = new clientThread(clientSocket, threads))
                        .start();
                  break;
               }
            }
            if (i == maxClientsCount) {
               PrintStream os = new PrintStream(clientSocket.getOutputStream());
               os.println("Server too busy. Try later.");
               os.close();
               clientSocket.close();
            }
         } catch (IOException e) {
            System.out.println(e);
         }
      }

   }
}

class clientThread extends Thread {

   private String clientName = null;
   private DataInputStream is = null;
   private PrintStream os = null;
   private Socket clientSocket = null;
   private final clientThread[] threads;
   private int maxClientsCount;

   public clientThread(Socket clientSocket, clientThread[] threads) {
      this.clientSocket = clientSocket;
      this.threads = threads;
      maxClientsCount = threads.length;
   }

   public void run() {
      int maxClientsCount = this.maxClientsCount;
      clientThread[] threads = this.threads;

      try {

         is = new DataInputStream(clientSocket.getInputStream());
         os = new PrintStream(clientSocket.getOutputStream());
         String name;
         while (true) {
            os.println("Enter your name.");
            name = is.readLine().trim();
            if (name.indexOf('@') == -1) {
               break;
            } else {
               os.println("The name should not contain '@' character.");
            }
         }

         os.println("Welcome " + name
               + " to our chat room.\nTo leave enter /quit in a new line.");
         synchronized (this) {
            for (int i = 0; i < maxClientsCount; i++) {
               if (threads[i] != null && threads[i] == this) {
                  clientName = "@" + name;
                  break;
               }
            }
            for (int i = 0; i < maxClientsCount; i++) {
               if (threads[i] != null && threads[i] != this) {
                  threads[i].os.println("*** A new user " + name
                        + " entered the chat room !!! ***");
               }
            }
         }

         while (true) {
            String line = is.readLine();
            if (line.startsWith("/quit")) {
               break;
            }

            if (line.startsWith("@")) {
               String[] words = line.split("\\s", 2);
               if (words.length > 1 && words[1] != null) {
                  words[1] = words[1].trim();
                  if (!words[1].isEmpty()) {
                     synchronized (this) {
                        for (int i = 0; i < maxClientsCount; i++) {
                           if (threads[i] != null && threads[i] != this
                                 && threads[i].clientName != null
                                 && threads[i].clientName.equals(words[0])) {
                              threads[i].os.println("<" + name + "> "
                                    + words[1]);

                              this.os.println(">" + name + "> " + words[1]);
                              break;
                           }
                        }
                     }
                  }
               }
            } else {

               synchronized (this) {
                  for (int i = 0; i < maxClientsCount; i++) {
                     if (threads[i] != null && threads[i].clientName != null) {
                        threads[i].os.println("<" + name + "> " + line);
                     }
                  }
               }
            }
         }
         synchronized (this) {
            for (int i = 0; i < maxClientsCount; i++) {
               if (threads[i] != null && threads[i] != this
                     && threads[i].clientName != null) {
                  threads[i].os.println("*** The user " + name
                        + " is leaving the chat room !!! ***");
               }
            }
         }
         os.println("*** Bye " + name + " ***");

         synchronized (this) {
            for (int i = 0; i < maxClientsCount; i++) {
               if (threads[i] == this) {
                  threads[i] = null;
               }
            }
         }

         is.close();
         os.close();
         clientSocket.close();
      } catch (IOException e) {
      }
   }
}


推荐答案


  1. 你应该在后台线程中监听客户端。您的代码当前没有这样做,因此您的服务器实际上已锁定在无限的中,而(true)循环。

  2. 您应该重构您的代码,以便您的方法不那么庞大和笨拙。

  3. 您应该重构您的代码,以便您的主要方法非常简短,以便它可以简单地关闭手表并开始运行,可以这么说。

  4. 格式化的代码非常难以阅读。请考虑编辑您的帖子并修复缩进样式,使其统一且一致。我通常避免使用制表符进行缩进(论坛软件通常不能很好地使用制表符)并缩进每个代码块4个空格。

  5. 你几乎不想让你的类扩展Thread。相反,让它实现Runnable(或使用Rod_Algonquin的优秀推荐)。

  6. 不要使用弃用的方法,例如 DataInputStream #readLine(...)因为这可能很危险。

  1. You should listen for clients in a background thread. Your code is not doing this currently and so your server is in fact locked in an endless while (true) loop.
  2. You should refactor your code so that your methods are not so large and unwieldy.
  3. You should refactor your code so that your main method is very brief, so that it simply winds the watch and starts it running, so to speak.
  4. Your code as formatted is very difficult to read. Please consider editing your post and fixing your indentation style so that it is uniform and consistent. I usually avoid using tabs for indenting (forum software often doesn't play well with tabs) and indent each code block 4 spaces.
  5. You almost never want to have your class extend Thread. Instead, have it implement Runnable (or use Rod_Algonquin's excellent recommendation).
  6. Don't use deprecated methods such as DataInputStream#readLine(...) as this could be dangerous to do.






例如,你的main可以这么简单...


For example, your main could be as simple as this...

public static void main(String[] args) {
   MyServer myServer = new MyServer();
   myServer.getThingsRunning();
}






编辑

注意添加为警告:我通常不使用套接字,服务器套件或创建聊天程序,我仍然是使用Executors的新手,但你可以构建你的代码这些行...


Edit
Note added as a warning: I don't generally work with sockets, serversockets, or create chat programs, and I'm still new at using Executors, but you could structure your code something along these lines...

public class MultiServer implements Runnable {
   public static final int PORT_NUMBER = 2222;
   private static final int THREAD_POOL_COUNT = 20;
   private List<MultiClient> clientList = new ArrayList<>();
   private ServerSocket serverSocket;
   private ExecutorService clientExecutor = Executors.newFixedThreadPool(THREAD_POOL_COUNT);

   public MultiServer() throws IOException {
      serverSocket = new ServerSocket(PORT_NUMBER);
   }

   @Override
   public void run() {
      // embed your socket acceptance loop in a Runnable's run method
      while (true) {
         try {
            Socket clientSocket = serverSocket.accept();
            MultiClient client = new MultiClient(clientSocket);
            clientList.add(client);
            clientExecutor.execute(client);
         } catch (IOException e) {
            // TODO notify someone of problem!
            e.printStackTrace();
         }
      }
   }

   // ..... more methods and such

   public static void main(String[] args) {
      try {
         MultiServer multiServer = new MultiServer();
         new Thread(multiServer).start();
      } catch (IOException e) {
         e.printStackTrace();
      }

   }
}

这篇关于多线程聊天服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆