套接字编程多客户端到一台服务器
你如何处理多个客户端连接到一台服务器? 我有这个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) { } } } } } }
和一个像这样的代码的一部分的embedded式小程序
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”,它将打开应用程序,并等待inputstream,如果我打开我的网站,它将开始stream日志。 但是,如果我使用其他计算机/networking再打开一个,则第二个站点不会loggingstream。 好像是因为第一个绑定到端口5000。
我该如何处理? socket如何与多个客户端/服务器一起工作?
对于每个客户你需要开始单独的线程。 例:
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; } } } }
您也可以使用更高级的解决scheme,使用NIOselect器,所以您不必为每个客户端创build线程,但是这有点复杂。
这是处理多个客户端的回声服务器…运行良好,使用线程
// echo server import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class Server_X_Client { public static void main(String args[]){ Socket s=null; ServerSocket ss2=null; System.out.println("Server Listening......"); try{ ss2 = new ServerSocket(4445); // can also use static final PORT_NUM , when defined } catch(IOException e){ e.printStackTrace(); System.out.println("Server error"); } while(true){ try{ s= ss2.accept(); System.out.println("connection Established"); ServerThread st=new ServerThread(s); st.start(); } catch(Exception e){ e.printStackTrace(); System.out.println("Connection Error"); } } } } class ServerThread extends Thread{ String line=null; BufferedReader is = null; PrintWriter os=null; Socket s=null; public ServerThread(Socket s){ this.s=s; } public void run() { try{ is= new BufferedReader(new InputStreamReader(s.getInputStream())); os=new PrintWriter(s.getOutputStream()); }catch(IOException e){ System.out.println("IO error in server thread"); } try { line=is.readLine(); while(line.compareTo("QUIT")!=0){ os.println(line); os.flush(); System.out.println("Response to Client : "+line); line=is.readLine(); } } catch (IOException e) { line=this.getName(); //reused String line for getting thread name System.out.println("IO Error/ Client "+line+" terminated abruptly"); } catch(NullPointerException e){ line=this.getName(); //reused String line for getting thread name System.out.println("Client "+line+" Closed"); } finally{ try{ System.out.println("Connection Closing.."); if (is!=null){ is.close(); System.out.println(" Socket Input Stream Closed"); } if(os!=null){ os.close(); System.out.println("Socket Out Closed"); } if (s!=null){ s.close(); System.out.println("Socket Closed"); } } catch(IOException ie){ System.out.println("Socket Close Error"); } }//end finally } }
也是这里是客户端的代码..只要执行此代码多次,你想创build多个客户端..
// A simple Client Server Protocol .. Client for Echo Server import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; public class NetworkClient { public static void main(String args[]) throws IOException{ InetAddress address=InetAddress.getLocalHost(); Socket s1=null; String line=null; BufferedReader br=null; BufferedReader is=null; PrintWriter os=null; try { s1=new Socket(address, 4445); // You can use static final constant PORT_NUM br= new BufferedReader(new InputStreamReader(System.in)); is=new BufferedReader(new InputStreamReader(s1.getInputStream())); os= new PrintWriter(s1.getOutputStream()); } catch (IOException e){ e.printStackTrace(); System.err.print("IO Exception"); } System.out.println("Client Address : "+address); System.out.println("Enter Data to echo Server ( Enter QUIT to end):"); String response=null; try{ line=br.readLine(); while(line.compareTo("QUIT")!=0){ os.println(line); os.flush(); response=is.readLine(); System.out.println("Server Response : "+response); line=br.readLine(); } } catch(IOException e){ e.printStackTrace(); System.out.println("Socket read Error"); } finally{ is.close();os.close();br.close();s1.close(); System.out.println("Connection Closed"); } } }
我想问题是你需要为每个连接启动一个单独的线程,并在一个循环中调用serverSocket.accept()来接受多个连接。 在同一个端口上有多个连接是不成问题的。