Android Socket程式設計學習筆記
通常也稱作"套接字",用於描述IP地址和埠,是一個通訊鏈的控制代碼。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並繫結到一個埠上,不同的埠對應於不同的服務。
網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個雙向鏈路的一端稱為一個Socket。Socket通常用來實現客戶方和服務方的連線。Socket是TCP/IP協議的一個十分流行的程式設計介面,一個Socket由一個IP地址和一個埠號唯一確定。
在java中,Socket和ServerSocket類庫位於java .net包中。ServerSocket用於伺服器端,Socket是建立網路連線時使用的。在連線成功時,應用程式兩端都會產生一個Socket例項,操作這個例項,完成所需的會話。
下面通過一個極為簡單的客戶端和服務端的連線例子演示下最基本的android socket通訊:
服務端的程式碼,在服務端特定的埠9999監聽客戶端請求,一旦有請求,便會執行,而後繼續監聽。使用accept()這個阻塞函式,就是該方法被呼叫後一直等待客戶端的請求,直到有請求且連線到同一個埠,accept()返回一個對應於客戶端的Socket。本例中很簡單,服務端不斷監聽,一旦有請求就輸出一段資訊:
<spanstyle="font-family:ComicSansMS;font-size:18px;">importjava.io.BufferedWriter;
importjava.io.IOException;
importjava.io.OutputStreamWriter;
importjava.net.ServerSocket;
importjava.net.Socket;
publicclassMain{
privatestaticfinalintPORT=9999;
publicstaticvoidmain(String[]args){
try{
//例項化伺服器套接字設定埠號9999
ServerSocketserver=newServerSocket(PORT);
while(true){
Socketsocket=server.accept();
//獲取輸出流
BufferedWriterwriter=newBufferedWriter(
newOutputStreamWriter(socket.getOutputStream()));
//寫字串
writer.write("這是一段來自伺服器的問候:Hello沃德!");
writer.flush();
writer.close();
}
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
</span>
下面是android客戶端的相關內容,介面有一個按鈕,點選後請求服務端的制定埠,然後顯示服務端的內容,值得注意的是在android4.0以上的系統中,是不允許在主執行緒裡面去執行網路相關的請求,否則會報錯:NetworkOnMainThreadException,所以本例中新開闢一個執行緒初始化socket的內容:
<spanstyle="font-family:ComicSansMS;font-size:18px;">packagecom.example.socketdemo;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.net.Socket;
importjava.net.UnknownHostException;
importandroid.annotation.SuppressLint;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.util.Log;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.TextView;
@SuppressLint("HandlerLeak")
publicclassSocketDemoextendsActivity{
/**Calledwhentheactivityisfirstcreated.*/
privateButtonbtn_receive;
privateTextViewtxt;
privateStringline;
privatestaticfinalStringHOST="192.168.1.101";
privatestaticfinalintPORT=9999;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initControl();
}
privatevoidinitControl(){
btn_receive=(Button)findViewById(R.id.btn_receive);
txt=(TextView)findViewById(R.id.txt);
btn_receive.setOnClickListener(newReceiverListener());
}
@SuppressLint("HandlerLeak")
classReceiverListenerimplementsOnClickListener{
@Override
publicvoidonClick(Viewv){
//TODOAuto-generatedmethodstub
newThread(){
@Override
publicvoidrun(){
//執行完畢後給handler傳送一個空訊息
try{
//例項化Socket
Socketsocket=newSocket(HOST,PORT);
//獲得輸入流
BufferedReaderbr=newBufferedReader(
newInputStreamReader(socket.getInputStream()));
line=br.readLine();
br.close();
}catch(UnknownHostExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
handler.sendEmptyMessage(0);
}
}.start();
}
}
//定義Handler物件
privateHandlerhandler=newHandler(){
@Override
//當有訊息傳送出來的時候就執行Handler的這個方法
publicvoidhandleMessage(Messagemsg){
super.handleMessage(msg);
//處理UI
txt.setText(line);
Log.i("PDA","----->"+line);
}
};
}
</span>
效果圖如下:
另外在配置檔案中記得加上許可權:<uses-permission android:name="android.permission.INTERNET">
測試的時候先啟動服務端,然後啟動客戶端,點選按鈕就可獲取到服務端資訊。這是在是一個灰常簡單的有關android socket的小例子,可以初步對socket有個簡單的瞭解,這個筆記就先記到這裡!
轉載於:https://my.oschina.net/bv10000/blog/306047