如何处理多个客户端以连接到一台服务器?我有这个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。
我该如何处理?套接字实际上如何与多个客户端/一台服务器一起工作?
对于每个客户端,你需要启动单独的线程。例:
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选择器,因此你不必为每个客户端创建线程,但这要复杂一些。