Android開發(fā)Socket編程
一.Socket簡介
1.所謂Socket通常也稱作“套接字”,用于描述IP地址和端口,是一個通信鏈的句柄
2.應(yīng)用程序通常通過“套接字”向網(wǎng)絡(luò)發(fā)送請求或者應(yīng)答網(wǎng)絡(luò)請求
3.Socket有兩種主要的操作方式:面向連接(TCP)的和無連接的(UDP)。
4.Java.net中提供了兩個類Socket和ServerSocket,分別用來表示雙向連接的客戶端和服務(wù)端。
一個客戶端要發(fā)起一次通信,首先必須知道運行服務(wù)器端的主機IP地址。然后由網(wǎng)絡(luò)基礎(chǔ)設(shè)施利用目標地址,將客戶端發(fā)送的信息傳遞到正確的主機上,在 Java中,地址可以由一個字符; 串來定 義,這個字符串可以使數(shù)字型的地址(比如192.168.1.1),也可以是主機名(example.com)。在 Java中InetAddress類代表了一個網(wǎng)絡(luò)目標地址,包括主機名和數(shù)字類型的地址信息。
二.使用基于TCP協(xié)議的Socket
1.ServerSocket:
ServerSocket:這個類是實現(xiàn)了一個服務(wù)器端的Socket,利用這個類可以監(jiān)聽來自網(wǎng)絡(luò)的請求。
(a)創(chuàng)建ServerSocket的方法:
ServerSocket(IntlocalPort)
ServerSocket(int localport,intqueueLimit)
ServerSocket(int localport,intqueueLimit,InetAddress localAddr)
創(chuàng)建一個ServerSocket必須指定一個端口,以便客戶端能夠向該端口號發(fā)送連接請求。端口的有效范圍是0-65535(0-1023是系統(tǒng)預(yù)留的,最好大于1024)
0~1023的端口號為系統(tǒng)所保留,例如http服務(wù)的端口號是80,telnet服務(wù)的端口號為21,ftp為23。所以我們在選擇端口號時最好選擇大 于1023的數(shù),防止發(fā)生沖突。在創(chuàng)建 Socket時,如果發(fā)生錯誤,將產(chǎn)生IOException,在程序中必須對其進行處理。所以在創(chuàng)建Socket 或ServerSocket時必須捕獲或拋出異常。
(b)ServerSocket操作
(1)Socketaccept()
accept()方法為下一個傳入的連接請求創(chuàng)建Socket實例,并將已成功連接的Socket實例返回給服務(wù)器套接字,如果沒有連接請求,accept()方法將阻塞等待;
(2)void close
close方法用于關(guān)閉套接字
2.Socket
(a)創(chuàng)建Socket的方法:
Socket(InetAddress remoteAddress,intremotePort)
利用Socket構(gòu)造函數(shù),可創(chuàng)建一個TCP套接字后,先連接到指定的遠程地址和端口號。
Socket(InetAddress address,int port ,InetAddress localAddr ,intlocalPort)
Socket(InetAddress address, int port ,booleanstream)
Socket(SocketImpl impl)
address、host、port分別表示雙向連接中另一方的IP地址、主機名、端口號
stream指明Socket是流Socket還是數(shù)據(jù)報Socket
localAddr,bindAddr是本地機器的地址(ServerSocket的主機地址)
impl是Socket的父類,既可以創(chuàng)建ServerSocket,也可創(chuàng)建Socket
(b)操作Socket的方法
通信過程中順序:服務(wù)器端首先得到輸入流,然后將輸入流信息輸出到其各個客戶端
Socket提供了getInputStream()和getOutputStream()方法來得到輸入輸出流。然后再對輸入流輸出流進行讀寫操作,例 如,對于服務(wù)器端,得到Socket對象后,調(diào)用getInputStream方法即 可得到來自客戶端的流,調(diào)用getOutStream方法可得到向客 戶端發(fā)送數(shù)據(jù)的流。對于客戶端,調(diào)用getInputStream方法即可得到來自服務(wù)器的流,調(diào)用getOutStream方法可得到向服務(wù)器端發(fā)送 數(shù) 據(jù)的流。
InputStreamgetInputStream()
OutputStreamgetOutputStream()
可調(diào)用Socket的close()方法進行關(guān)閉,在關(guān)閉前,應(yīng)將與Socket相關(guān)的所有輸入輸出流關(guān)閉,正著打開,倒著關(guān)閉。
3.編程步驟:
創(chuàng)建服務(wù)器的步驟:
指定端口實例化一個ServerSocket調(diào)用ServerSocket的accept方法以在等待連接期間造成阻塞獲取位于該底層Socket的流以進行讀寫操作將數(shù)據(jù)封裝成流對Socket進行讀寫關(guān)閉打開的流
創(chuàng)建客戶端的步驟:
通過IP地址和端口實例化Socket,請求連接服務(wù)器獲取Socket上的流以進行讀寫把流包裝進BufferedReader/PrintWriter的實例對Socket進行讀寫關(guān)閉打開的流
當要監(jiān)控多個客戶端時,可使用類ExecutorService
其對象獲取方法:Executors.newCachedThreadPool();
調(diào)用該對象的execute(Runnablecommand)即可,在未來某個時間執(zhí)行給定的命令。該命令可能在新的線程、已入池的線程或者正調(diào)用的線程中執(zhí)行,這由Executor實現(xiàn)決定
三.使用基于UDP的Socket
(a)創(chuàng)建DatagramSocket
DatagramSocket(byte [] data,intoffset,int length,InetAddress remoteAddr,intremotePort)
該構(gòu)造函數(shù)創(chuàng)建一個數(shù)據(jù)報文對象,數(shù)據(jù)包含在第一個參數(shù)data當中
Offset是指偏移量長度,length是指數(shù)據(jù)包長度。
(b)創(chuàng)建DatagramSocket
DatagramSocket(intlocalPort)
以上構(gòu)造函數(shù)將創(chuàng)建一個UDP套接字;
(c)DatagramSocket:發(fā)送和接受
void send(DatagramPacketpacket)
void receive(DatagramPacketpacket)
send()方法用來發(fā)送DatagramPacket實例。一旦創(chuàng)建連接,數(shù)據(jù)報將發(fā)送到該套接字所連接的地址;
receive()方法將阻塞等待,知道接收到數(shù)據(jù)報文,并將報文中的數(shù)據(jù)復(fù)制到指定的DatagramPacket實例中。
補充:
對AndroidManifest.xml的配置一定不要忘了:
<uses-permissionandroid:name="android.permission.INTERNET"/>
輸入和輸出流要用DataOutputStream和DataOutputStream,不可以用PrintWriter、StreamReader等。
【編輯推薦】