概述
Java 网络编程的客户端和服务端编写都非常简单。客户端使用 Socket 对象与服务端交互;服务端创建 ServerSocket 对象,然后使用accept()方法进行监听,并返回一个Socket的对象。accept 方法是阻塞调用,并将一直阻塞,直到接收到下一个客户端请求为止。非多线程情况下,服务器同时只能服务一个客户端。这通常是不能满足现实需求的。
对于现实场景是通过在服务端创建多个线程来服务多个客户端,如下图:

服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.concurrent.ExecutorService
; import java.util.concurrent.Executors;
public class EchoMultiServer { private static ServerSocket server = null; private static ExecutorService threadPool;
public static void main(String[] args) { threadPool = Executors.newCachedThreadPool(); threadPool.submit(new Monitor
());
try { server = new ServerSocket(10000);
System.out.println("Server listening on port 10000 ...."); System.out.println("Hit Enter to stop the server");
while (true) { Socket socket = server.accept(); System.out.println("Thread created"); threadPool.submit(new EchoThread
(socket)); } } catch (SocketException e) { System.out.println("Server is down"); } catch (IOException e) { e.printStackTrace(); } }
private static void shutdownServer() { try { server.close(); } catch (IOException e) { e.printStackTrace(); }
threadPool.shutdown(); System.exit(0); }
private static class Monitor implements Runnable {
@Override public void run() { try { while (System.in.read() != '\n') {} } catch (IOException e) { }
shutdownServer(); } } }
class EchoThread implements Runnable { private Socket socket = null; private byte[] buffer = new byte[512];
public EchoThread(Socket socket) { this.socket = socket; }
@Override public void run() { try { InputStream is = socket.getInputStream(); is.read(buffer); OutputStream os = socket.getOutputStream(); os.write(buffer); } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress
; import java.net.Socket; import java.util.Scanner;
public class EchoMultiClient { private static int counter;
public static void main(String[] args) { for (int i = 0; i < 100; i++) { counter++; new Thread(new Client(counter)).start(); } }
private static class Client implements Runnable { private int counter;
public Client(int counter) { this.counter = counter; }
@Override public void run() { try { Socket socket = new Socket(); socket.connect(new InetSocketAddress("localhost", 10000), 1000);
try { OutputStream os = socket.getOutputStream(); String str = "Hello from Client " + counter; os.write(str.getBytes()); InputStream is = socket.getInputStream(); Scanner scanner = new Scanner(is); while (scanner.hasNextLine()) { System.out.println(scanner.nextLine()); }
Thread.sleep(10); scanner.close(); } finally { socket.close(); } } catch (Exception e) { e.printStackTrace(); } } } }
|