通过套接字将多个客户端编程到一台服务器

发布于 2021-02-02 22:42:48

如何处理多个客户端以连接到一台服务器?我有这个LogServer.java

import javax.net.ssl.*;
import javax.net.*;
import java.io.*;
import java.net.*;

public class LogServer {
  private static final int PORT_NUM = 5000;
  public static void main(String args[]) {
    ServerSocketFactory serverSocketFactory =
      ServerSocketFactory.getDefault();
    ServerSocket serverSocket = null;
    try {
      serverSocket =
        serverSocketFactory.createServerSocket(PORT_NUM);
    } catch (IOException ignored) {
      System.err.println("Unable to create server");
      System.exit(-1);
    }
    System.out.printf("LogServer running on port: %s%n", PORT_NUM);
    while (true) {
      Socket socket = null;
      try {
        socket = serverSocket.accept();
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(
          new InputStreamReader(is, "US-ASCII"));
        String line = null;
        while ((line = br.readLine()) != null) {
          System.out.println(line);
        }
      } catch (IOException exception) {
        // Just handle next request.
      } finally {
        if (socket != null) {
          try {
            socket.close();
          } catch (IOException ignored) {
          }
        }
      }
    }
  }
}

和一个嵌入式小程序,其中包含部分代码,例如

import java.io.*;
import java.util.logging.*;

public class LogTest
{
  private static Logger logger = Logger.getAnonymousLogger();

  public static void main(String argv[]) throws IOException
  {
    Handler handler = new SocketHandler("localhost", 5000);
    logger.addHandler(handler);
    logger.log(Level.SEVERE, "Hello, World");
    logger.log(Level.SEVERE, "Welcome Home");
    logger.log(Level.SEVERE, "Hello, World");
    logger.log(Level.SEVERE, "Welcome Home");
  }
}

现在的问题是,如果我在服务器上运行“ java LogServer”,它将打开应用程序并等待输入流,如果打开站点,它将开始流式传输日志。但是,如果我使用其他计算机/网络再打开一个,则第二个站点不会记录该流。似乎是因为第一个仍绑定到端口5000。

我该如何处理?套接字实际上如何与多个客户端/一台服务器一起工作?

关注者
0
被浏览
92
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    对于每个客户端,你需要启动单独的线程。例:

    public class ThreadedEchoServer {
    
        static final int PORT = 1978;
    
        public static void main(String args[]) {
            ServerSocket serverSocket = null;
            Socket socket = null;
    
            try {
                serverSocket = new ServerSocket(PORT);
            } catch (IOException e) {
                e.printStackTrace();
    
            }
            while (true) {
                try {
                    socket = serverSocket.accept();
                } catch (IOException e) {
                    System.out.println("I/O error: " + e);
                }
                // new thread for a client
                new EchoThread(socket).start();
            }
        }
    }
    

    public class EchoThread extends Thread {
        protected Socket socket;
    
        public EchoThread(Socket clientSocket) {
            this.socket = clientSocket;
        }
    
        public void run() {
            InputStream inp = null;
            BufferedReader brinp = null;
            DataOutputStream out = null;
            try {
                inp = socket.getInputStream();
                brinp = new BufferedReader(new InputStreamReader(inp));
                out = new DataOutputStream(socket.getOutputStream());
            } catch (IOException e) {
                return;
            }
            String line;
            while (true) {
                try {
                    line = brinp.readLine();
                    if ((line == null) || line.equalsIgnoreCase("QUIT")) {
                        socket.close();
                        return;
                    } else {
                        out.writeBytes(line + "\n\r");
                        out.flush();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    }
    

    你还可以使用更高级的解决方案,该解决方案使用NIO选择器,因此你不必为每个客户端创建线程,但这要复杂一些。



推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看