Socket中文譯做「套接字」,也稱爲伯克利套接字和BSD套接字(Berkeley Software Distribution,伯克利軟件套件),BSD是伯克利大學基於早期UNIX系統的衍生系統。伯克利套接字java
的應用編程接口(API)是使用C語言的進程間通訊的庫,常常用於計算機網絡間通訊。BSD Socket的應用編程接口已是網絡套接字的事實上的抽象標準。編程
BSD Socket做爲一種API,容許不一樣主機或者同一個計算機上的不一樣進程之間的通訊。它支持多種I/O設備和驅動,可是具體的實現是依賴操做系統的。這種接口對於TCP/IP是必不可少的,因此是互聯網的基礎技術之一。它最初是由加州伯克利大學爲Unix系統開發出來的。全部現代的操做系統都都實現了伯克利套接字接口,由於它已是鏈接互聯網的標準接口了。服務器
Socket鏈接過程分爲三步:服務器監聽,客戶端請求,鏈接確認。以JAVA爲例,Socket和ServerSocket類位於java.net包中,ServerSocket用於服務器端,Socket是創建網絡鏈接時使用的。在鏈接成功時,應用程序兩端都會都會產生一個Socket實例,操做這個實例,完成所需的會話。對於一個網絡鏈接來講,套接字是平等的,並無差異,不由於在服務器端或在客戶端而產生不一樣級別。無論是Socket仍是ServerSocket它們的工做都是經過SocketImpl類及其子類完成的。網絡
JAVA中使用實例框架
服務端(Server)ide
import java.net.*; import java.io.*; import java.util.*; public class Server { boolean isstart = false;//用來判斷 服務端是否已經起來了 //public DataInputStream dis = null; //public String str = null; public ServerSocket ss = null; //public Socket s = null; List<Client> clients = new ArrayList<>(); //DataOutputStream dos = null; public static void main(String[] args) //要屢次調用readUTF()方法 Client端 發送多少次給服務端 服務端就要接受多少次 用到死循環 { new Server().start(); } public void start() { try { ss = new ServerSocket(8888);//服務端起來了 isstart = true;//服務端起來後 將其設置爲 true } catch(BindException e)//這個異常必定要 先比 IOException 先 捕獲 否則 若是先捕獲 IOException 這個 異常就捕獲不了了 而後就會報錯 提示要先捕獲 這個異常 { System.out.println("端口使用中……"); System.out.println("請關掉服務端 ,而後從新啓動服務端。"); System.exit(0); } catch(IOException e) { e.printStackTrace(); } try { while(isstart)//服務端起來後就一直 循環 檢測是否有客戶端鏈接 { Socket s = ss.accept();//客戶端鏈接到服務端後 設置其爲true System.out.println("a client connect"); Client c = new Client(s); clients.add(c); new Thread(c).start(); } } catch(IOException e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } class Client implements Runnable { private Socket s = null; private DataInputStream dis = null; DataOutputStream dos = null; private boolean isconnect = false; Client(Socket s) { this.s = s; try { dis = new DataInputStream(s.getInputStream());//客戶端鏈接到服務端後 設置isconnect = true dos = new DataOutputStream(s.getOutputStream()); isconnect = true; } catch (IOException e) { e.printStackTrace(); } } public void send(String str) { try { dos.writeUTF(str); dos.flush(); } catch (IOException e) { clients.remove(this); System.out.println("a client quit"); } } @Override public void run() { try { while(isconnect)//客戶端鏈接服務端後 循環 以便 接受 客戶端 每一次發送的消息 { //dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); System.out.println(str); for(int i=0;i<clients.size();i++) { Client c = clients.get(i); c.send(str); } //dis.close(); //ss.close(); } //dis.close();//當服務端沒有起來 或者 客戶端沒有鏈接 到服務端 就將管道關閉*/ } catch(EOFException e) { System.out.println("Client disconnect!"); } catch (IOException e) { e.printStackTrace(); } finally { try { if(dis!=null) dis.close(); if(s!=null) s.close(); } catch(IOException e) { e.printStackTrace(); } System.out.println("Client disconnect!"); } } } }
客戶端(Client)ui
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Client extends Frame { TextField txf = new TextField(); //TextField txf = null; //應該先要進行初始化 否則 txa.setText(txa.getText()+str+"\n");用於記錄聊天記錄的語句就會 每次都爲null 記錄保存不了 TextArea txa = new TextArea(); DataOutputStream dos = null; DataInputStream dis = null; Socket s = null; boolean isconnect = false; Thread receive = new Thread(new Receive());//new Receive()別忘了!! public static void main(String[] args) { new Client().lanuch(); } public void lanuch() { Frame frame = new Frame("Chat!"); frame.setLayout(new BorderLayout()); frame.setLocation(200,300); frame.setSize(200, 150); //txf = new TextField(); //txa = new TextArea(); frame.add(txf, BorderLayout.SOUTH);//增長兩個框架的順序也是有前後的 frame.add(txa, BorderLayout.CENTER);// txf.addActionListener(new TxfListener()); //txa.setEditable(false); frame.pack(); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { disconnect(); System.exit(0); } }); connected(); } public void disconnect() { try { dos.close(); s.close(); } catch(IOException e) { e.printStackTrace(); } } public void connected() { try { s = new Socket("127.0.0.1",8888); dos = new DataOutputStream(s.getOutputStream()); dis = new DataInputStream(s.getInputStream()); isconnect = true; receive.start(); } catch(IOException e) { e.printStackTrace(); } System.out.println("connect"); } class Receive implements Runnable { public void run() { try { while(isconnect) { String str = dis.readUTF(); txa.setText(txa.getText()+str+"\n"); } } catch(SocketException e) { System.out.println("系統退出……"); } catch(IOException e) { e.printStackTrace(); } } } private class TxfListener implements ActionListener { public void actionPerformed(ActionEvent e) { String str = txf.getText(); //txa.setText(str); txf.setText(""); try { dos.writeUTF(str); dos.flush(); //dos.close(); //s.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }
參考文章:https://blog.csdn.net/wang_hua_yi/article/details/17382015this