Android網絡編程-Socket

Socket在Android網絡編程中,有著非常重要的作用。

Socket基本概念

即套接字,是應用層 與 TCP/IP 協議族通信的中間軟件抽象層,表現為一個封裝了 TCP / IP協議族 的編程接口(API)。
從設計模式的角度看來,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數據,以符合指定的協議。
借用下網上結構圖:

Android網絡編程-Socket

Socket


IP地址和端口號組成了Socket,都是成對出現。


<code>Socket ={(IP地址1:PORT端口號),(IP地址2:PORT端口號)}/<code>

單獨的Socke是沒用任何作用的,基於一定的協議(TCP或者UDP)下的Socket編程才能進行數據傳輸。

Socket工作流程


Android網絡編程-Socket

Socket工作流程


服務端先初始化Socket,然後與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端連接。
客戶端初始化一個socket,然後連接服務器(connect),如果連接成功,這時客戶端與服務端的連接就建立了。
客戶端發送數據請求,服務端接收請求並處理請求,然後把回應數據發給客戶端,客戶端讀取數據,最後關閉數據,一次交互結束。


分類

Socket使用類型有兩種:

  • 基於TCP協議,流套接字,採用流的方式提供可靠的字節流服務
  • 基於UDP協議,數據報套接字,採用數據報文提供數據打包發送的服務

基於TCP的Socket編程

主要API

Socket

構造方法

<code>public Socket(String host, int port)        throws UnknownHostException, IOException/<code>

創建流套接字並將其連接到指定主機上的指定端口號。

  • host: 主機地址
  • port: 端口號

getInputStream

返回Socket的輸入流,用戶接受數據。

getOutputStream

返回Socket的輸出流,用於發送數據。

ServerSocket

Socket的服務端實現

構造函數

<code>public ServerSocket(int port) throws IOException/<code>

創建服務端Socket,綁定到指定端口。

  • port: 端口號

accept

<code>public Socket accept() throws IOException/<code>

監聽並接受到此套接字的連接。該方法將阻塞,直到建立連接。

示例

服務端

<code>public class Server {    public static void main(String[] args) throws IOException {        //1. 創建ServerSocket        ServerSocket serverSocket = new ServerSocket(8888);        //2. 監聽        Socket socket = serverSocket.accept();        System.out.println("server start listen");        //3. 輸入流        InputStream is = socket.getInputStream();        InputStreamReader reader = new InputStreamReader(is);        BufferedReader br = new BufferedReader(reader);        String content = null;        StringBuffer sb = new StringBuffer();        while ((content = br.readLine()) != null) {            sb.append(content);        }        System.out.println("server receiver: " + sb.toString());        socket.shutdownInput();        br.close();        reader.close();        is.close();        socket.close();        serverSocket.close();    }}/<code>

非常簡單的Socket服務端,接收到客戶端的數據,就會關閉當前的連接。這個示例只是展示了一個完整的流程。
如果需要複雜的服務端實現,可以使用Netty、Mina或者其他Socket框架。

客戶端

<code>//1. 創建客戶端Socket socket = new Socket("your ip", 8888);//2. 輸出流OutputStream os = socket.getOutputStream();//3. 發送數據os.write("Hello world".getBytes());System.out.println("send message");os.flush();socket.shutdownOutput();os.close();socket.close();/<code>

客戶端就是連接後,發送了一份數據,就關閉連接了。
這樣就實現了客戶端和服務端的通信。

基於UDP的Socket編程

主要API

DatagramPacket

用來包裝接收和發送的數據。

  • 構造接收數據包
<code>public DatagramPacket(byte[] buf,int length)/<code>

用來接收長度為 length 的數據包。

  • 構造發送數據包
<code>DatagramPacket(byte[] buf, int length,SocketAddress address)DatagramPacket(byte[] buf, int length, InetAddress address, int port)/<code>

用來將長度為 length 的包發送到指定主機上的指定端口號。

DatagramSocket

用來發送和接收數據報包的套接字。

構造方法

<code>//創建數據報套接字並將其綁定到本地主機上的指定端口DatagramSocket(int port)  //創建數據報套接字,將其綁定到指定的本地地址DatagramSocket(int port, InetAddress laddr)/<code>

發送數據

<code>void send(DatagramPacket p)/<code>

DatagramPacket 包含的信息指示:將要發送的數據、其長度、遠程主機的 IP 地址和遠程主機的端口號

接收數據

<code>void receive(DatagramPacket p)/<code>

當此方法返回時,DatagramPacket的緩衝區填充了接收的數據。

示例

服務端

<code>public class UDPServer {    public static void main(String[] args) throws IOException {        byte[] buf = new byte[1024];        // receive        // 1.create        DatagramPacket packet = new DatagramPacket(buf, buf.length);        // 2.create udp socket        DatagramSocket socket = new DatagramSocket(8888);        // 3. receive start        socket.receive(packet);        // 4. receive data        System.out.println("sever: " + new String(buf, 0, buf.length));        // send        DatagramPacket p = new DatagramPacket(buf, buf.length,                         packet.getAddress(), packet.getPort());        socket.send(p);        socket.close();    }}/<code>

客戶端

<code>// sendInetAddress address = InetAddress.getByName("your ip");//1.create packetDatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, 8888);//2.create socketDatagramSocket socket = new DatagramSocket();//3.send datasocket.send(packet);// receive//1.create packetfinal byte[] bytes = new byte[1024];DatagramPacket receiverPacket = new DatagramPacket(bytes, bytes.length);socket.receive(receiverPacket);System.out.println("client: " + new String(bytes, 0, bytes.length));socket.close();/<code>

客戶端和服務端的實現,都比較簡單。

關於Socket編程,就介紹好了,這篇只是開了頭,最主要的還是得去項目中實踐。

參考

  • Android:這是一份很詳細的Socket使用攻略
  • Scoket編程


分享到:


相關文章: