一、實現:實現服務端與客戶端一對多的關係;服務端關閉則客戶端等待服務端啓動後重連,客戶端關閉則服務端關閉與服務端的socket鏈接,若是全部客戶端關閉,則服務端等待客戶端鏈接。java
實現客戶端向服務端單向發送數據(服務端向客戶端發送數據同理)。服務器
二、服務端:socket
A、服務器端建立ServerSocket,循環調用accept()等待客戶端鏈接ide
B、客戶端建立一個socket並請求和服務器端鏈接this
C、服務器端接受客戶端請求,建立socket與該客戶創建專線鏈接spa
D、創建鏈接的兩個socket在一個單獨的線程上對話.net
E、服務器端繼續等待新的鏈接線程
代碼:code
import java.io.IOException; import java.io.ObjectInputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; public class SocketServer { private static ServerSocket serverSocket = null; private static Map<String, ModelClass> info = new ConcurrentHashMap<>(); static { try { serverSocket = new ServerSocket(9090); } catch (IOException e) { System.out.println("create serverSocket error: " + e.getMessage()); } } public static void main(String[] args) throws IOException { // 定時打印接收到的數據 new Thread(new Runnable( ) { @Override public void run() { while (true) { Iterator<Map.Entry<String, ModelClass>> it = info.entrySet().iterator(); while(it.hasNext()) { Entry<String, ModelClass> entry = it.next(); ModelClass mc = entry.getValue(); System.out.println(mc.name); System.out.println(mc.m1.get(0)); System.out.println(mc.m2.get(0).value); System.out.println(); } try { Thread.sleep(5000); } catch (InterruptedException e) { System.out.println(e.getMessage()); } } } }).start(); // 等待客戶端鏈接 new Thread(new Runnable() { @Override public void run() { while (true) { try { System.out.println("*****服務器已啓動,等待客戶端鏈接*****"); Socket socket = serverSocket.accept(); System.out.println("*****已鏈接客戶端*****"); new SST(socket).start(); } catch (Exception e) { System.out.println("socket accept error: " + e.getMessage()); } } } }).start(); } static class SST extends Thread { private Socket socket; private String key; public SST(Socket socket) { this.socket = socket; key = socket.getInetAddress().toString() + "/" + socket.getPort(); } @Override public void run() { // BufferedReader br = null; // 讀取客戶端輸入的文件流 ObjectInputStream ois = null; // 讀取客戶端輸入的對象流 try { while (true) { // br = new BufferedReader(new InputStreamReader(socket.getInputStream())); // String msg = null; // while((msg = br.readLine()) != null) { // System.out.println("get msg---" + socket.getInetAddress() + "/" + socket.getPort()); // System.out.println("client msg: " + msg); // } ois = new ObjectInputStream(socket.getInputStream()); Object obj = ois.readObject(); ModelClass mc = (ModelClass)obj; info.put(key, mc); } } catch (Exception e) { System.out.println("get msg error: " + e.getMessage()); } finally { if (info.containsKey(key)) { info.remove(key); } try { // if (br != null) { // br.close(); // } if (ois != null) { ois.close(); } } catch (IOException e) { System.out.println("br close error: " + e.getMessage()); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { System.out.println(e.getMessage()); } } } } } } }
三、客戶端:server
A、用服務器的IP地址和端口號實例化Socket對象。
B、得到Socket上的流,以進行讀寫。
C、關閉打開的流和Socket。
代碼:
import java.io.ObjectOutputStream; import java.net.Socket; public class SocketClient { ModelClass mc; public SocketClient() { new Thread(new Runnable() { @Override public void run() { try { client(); } catch (Exception e) { System.out.println(e.getMessage()); } } }).start(); } public void send(ModelClass mc) { this.mc = mc; } private void client() throws Exception { Socket socket = null; ObjectOutputStream oos = null; try { while(true) { System.out.println("create new socket!"); try { socket = new Socket("127.0.0.1", 9090); while (true) { if (mc == null) { Thread.sleep(1000); continue; } System.out.println("out object!"); oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeObject(mc); mc = null; } } catch (Exception e) { System.out.println("socket error: " + e.getMessage()); } Thread.sleep(5000); } } finally { if (socket != null) { socket.close(); } if (oos != null) { oos.close(); } } } }
四、客戶端實例:
import socket.ModelClass.InnerModel; import socket.ModelClass.Status; public class Client2 { private static SocketClient client; public static void main(String[] args) throws Exception { client = new SocketClient(); new Client2().func(); } public void func() throws InterruptedException { ModelClass mc = new ModelClass(); mc.name = "client2"; mc.m1.add(Status.NA); mc.m2.clear(); InnerModel im = new InnerModel(); while(true) { im.value = "client2: " + System.currentTimeMillis(); mc.m2.add(im); client.send(mc); Thread.sleep(2000); } } }
五、對象model:
import java.io.Serializable; import java.util.ArrayList; import java.util.List; public class ModelClass implements Serializable { private static final long serialVersionUID = 1000L; String name; List<Status> m1 = new ArrayList<>(); List<InnerModel> m2 = new ArrayList<>(); static class InnerModel implements Serializable { private static final long serialVersionUID = 1001L; String value; } public enum Status { OK, ERROR, NA, WARNING, FATAL; } }