Android網絡編程-Socket

Socket在Android網絡編程中,有着很是重要的做用。html

Socket基本概念

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

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

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

Socket工做流程

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

分類

Socket使用類型有兩種:編程

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

基於TCP的Socket編程

主要API

Socket

構造方法

public Socket(String host, int port)
        throws UnknownHostException, IOException

建立流套接字並將其鏈接到指定主機上的指定端口號。設計模式

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

getInputStream

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

getOutputStream

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

ServerSocket

Socket的服務端實現app

構造函數

public ServerSocket(int port) throws IOException

建立服務端Socket,綁定到指定端口。框架

  • port: 端口號

accept

public Socket accept() throws IOException

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

示例

服務端

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();
    }
}

很是簡單的Socket服務端,接收到客戶端的數據,就會關閉當前的鏈接。這個示例只是展現了一個完整的流程。
若是須要複雜的服務端實現,能夠使用Netty、Mina或者其餘Socket框架。

客戶端

//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();

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

基於UDP的Socket編程

主要API

DatagramPacket

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

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

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

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

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

DatagramSocket

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

構造方法

//建立數據報套接字並將其綁定到本地主機上的指定端口
DatagramSocket(int port)  

//建立數據報套接字,將其綁定到指定的本地地址
DatagramSocket(int port, InetAddress laddr)

發送數據

void send(DatagramPacket p)

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

接收數據

void receive(DatagramPacket p)

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

示例

服務端

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();
    }
}

客戶端

// send
InetAddress address = InetAddress.getByName("your ip");
//1.create packet
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, 8888);
//2.create socket
DatagramSocket socket = new DatagramSocket();
//3.send data
socket.send(packet);
// receive
//1.create packet
final 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();

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

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

參考

本篇文章由一文多發平臺 ArtiPub自動發佈
相關文章
相關標籤/搜索