2015武大-終端第三天上午0android網(wǎng)絡(luò)編程_第1頁(yè)
2015武大-終端第三天上午0android網(wǎng)絡(luò)編程_第2頁(yè)
2015武大-終端第三天上午0android網(wǎng)絡(luò)編程_第3頁(yè)
2015武大-終端第三天上午0android網(wǎng)絡(luò)編程_第4頁(yè)
2015武大-終端第三天上午0android網(wǎng)絡(luò)編程_第5頁(yè)
已閱讀5頁(yè),還剩55頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

武漢大學(xué)谷歌聯(lián)合實(shí)驗(yàn)室Android-網(wǎng)絡(luò)編程主要內(nèi)容1、網(wǎng)絡(luò)編程概述2、Android對(duì)網(wǎng)絡(luò)通信的支持3、HTTP通信4、Socket通信1、網(wǎng)絡(luò)編程概述—網(wǎng)絡(luò)通信協(xié)議及接口網(wǎng)絡(luò)通信協(xié)議就是對(duì)計(jì)算機(jī)之間通信的信息格式、能被收/發(fā)雙方接受的傳送信息內(nèi)容的一組定義。即連接不同操作系統(tǒng)和不同硬件體系結(jié)構(gòu)的互聯(lián)網(wǎng)絡(luò)提供通信支持,是一種網(wǎng)絡(luò)通用語(yǔ)言。網(wǎng)絡(luò)通信接口為了使兩個(gè)結(jié)點(diǎn)能進(jìn)行對(duì)話,必須在它們之間建立通信工具(即接口),使彼此之間能進(jìn)行信息交換。接口包括兩部分:硬件裝置:實(shí)現(xiàn)結(jié)點(diǎn)之間的信息傳送軟件裝置:規(guī)定雙方進(jìn)行通信的約定協(xié)議通信協(xié)議的分層思想為什么要分層由于結(jié)點(diǎn)之間聯(lián)系復(fù)雜,在制定協(xié)議時(shí),把復(fù)雜成份分解成一些簡(jiǎn)單的成份,再將它們復(fù)合起來(lái)。最常用的復(fù)合方式是層次方式,即同層間可以通信,上一層可以調(diào)用下一層,而與再下一層沒有關(guān)系。各層互不影響,利于系統(tǒng)的開發(fā)和擴(kuò)展。通信協(xié)議的分層規(guī)定把用戶應(yīng)用程序作為最高層,把物理通信線路作為最底層,將期間的協(xié)議處理分為若干層,規(guī)定每層處理的任務(wù),也規(guī)定每層的接口標(biāo)準(zhǔn)。參考模型數(shù)據(jù)封裝數(shù)據(jù)拆封IP協(xié)議IP協(xié)議就是為計(jì)算機(jī)網(wǎng)絡(luò)相互連接進(jìn)行通信而設(shè)計(jì)的協(xié)議。在因特網(wǎng)中,它是能使連接到網(wǎng)上的所有計(jì)算機(jī)網(wǎng)絡(luò)實(shí)現(xiàn)相互通信的一套規(guī)則,規(guī)定了計(jì)算機(jī)在因特網(wǎng)上進(jìn)行通信時(shí)應(yīng)當(dāng)遵守的規(guī)則。任何廠家生產(chǎn)的計(jì)算機(jī)系統(tǒng),只要遵守IP協(xié)議就可以與因特網(wǎng)互連互通。TCP協(xié)議和UDP協(xié)議TCP協(xié)議

TCP是專門設(shè)計(jì)用于在不可靠的因特網(wǎng)上提供可靠的、端到端的字節(jié)流通信的協(xié)議。它是一種面向連接的協(xié)議,TCP連接的是字節(jié)流而非報(bào)文流。UDP協(xié)議:

UDP向應(yīng)用程序提供了一種發(fā)送封裝的原始IP數(shù)據(jù)報(bào)的方法,并且發(fā)送時(shí)無(wú)需建立連接。是一種不可靠的連接。TCP/UDP區(qū)別編程時(shí)區(qū)別:利用TCP協(xié)議進(jìn)行通信的兩個(gè)應(yīng)用程序是有主次之分,一個(gè)稱為服務(wù)器程序,另外一個(gè)稱為為客戶機(jī)程序,兩者功能和編寫方法大不一樣。利用UDP通信的兩個(gè)程序是平等的,沒有主次之分,2個(gè)程序代碼可以是完全一樣的??蛻舳?服務(wù)器模式又稱為智能服務(wù)器/智能客戶端體系結(jié)構(gòu)服務(wù)器和客戶端共同承擔(dān)計(jì)算客戶端向另一臺(tái)計(jì)算機(jī)請(qǐng)求服務(wù)的計(jì)算機(jī)服務(wù)器處理客戶端請(qǐng)求的計(jì)算機(jī)優(yōu)點(diǎn)服務(wù)器和客戶端分?jǐn)偣ぷ鞣?wù)器可以同時(shí)為數(shù)千臺(tái)客戶端服務(wù)多個(gè)客戶端可以同時(shí)訪問(wèn)服務(wù)器2、Android對(duì)網(wǎng)絡(luò)通信的支持Android平臺(tái)為網(wǎng)絡(luò)通信提供了豐富的API,有3種網(wǎng)絡(luò)接口。分別是:.*(標(biāo)準(zhǔn)JAVA接口)提供與聯(lián)網(wǎng)有關(guān)的類,包括流和數(shù)據(jù)包套接字、Internet協(xié)議,常見HTTP處理。例如:URL以及URLConnection/HttpURLConnection對(duì)象、設(shè)置連接參數(shù)、連接到服務(wù)器、向服務(wù)器寫數(shù)據(jù)、從服務(wù)器讀取數(shù)據(jù)等通信。org.apache(Apache接口)JDK的已經(jīng)提供了訪問(wèn)HTTP協(xié)議的基本功能,但遠(yuǎn)遠(yuǎn)不夠。開源項(xiàng)目HttpClient。主要包括創(chuàng)建HttpClient以及Get/Post、HttpRequest等對(duì)象,設(shè)置連接參數(shù),執(zhí)行HTTP操作,處理服務(wù)器返回結(jié)果等功能。.*(Android網(wǎng)絡(luò)接口)通過(guò)對(duì)Apache中HttpClient的封裝來(lái)實(shí)現(xiàn)的一個(gè)HTTP編程接口。同時(shí)還提供了HTTP請(qǐng)求隊(duì)列管理以及HTTP連接池管理等等。2、Android對(duì)網(wǎng)絡(luò)通信的支持Android平臺(tái)將Apache旗下的Http通信相關(guān)的org.apache.http包也納入到系統(tǒng)來(lái)。2).ssl包中主要類/接口說(shuō)明1)包中主要類/接口說(shuō)明類/接口功能說(shuō)明ServerSocket表示用于等待客戶端連接的服務(wù)方的套接字Socket提供一個(gè)客戶端的TCP套接字DatagramSocket實(shí)現(xiàn)一個(gè)用于發(fā)送和接收數(shù)據(jù)報(bào)的UDP套接字?jǐn)?shù)據(jù)包IntetAddress表示IP地址UnkownHostException位置主機(jī)異常HttpURLConnection用于管理Http鏈接(RFC2068)的資源連接管理器URL用于指定互聯(lián)網(wǎng)上1個(gè)資源的位置信息(RFC1783)類/接口功能說(shuō)明HttpsURLConnection用于管理Https連接(RFC2818)的資源連接管理器SSLSocket提供安全協(xié)議的套接字SSLServerSocket基于SSL、TLS等協(xié)議的安全服務(wù)套接字SSLContextSSL上下文環(huán)境APITrustManagerFactory信任管理器KeyManagerFactory密鑰管理器2、Android對(duì)網(wǎng)絡(luò)通信的支持關(guān)于這方面更多地內(nèi)容:參考Android的SDKorg.apacke.http.impl.client包主要類/接口說(shuō)明類/接口功能說(shuō)明DefaultHttpClient表示一個(gè)Http客戶端默認(rèn)實(shí)現(xiàn)接口org.apacke.http.client.methods包中主要類/接口說(shuō)明類/接口功能說(shuō)明HttpGet/HttpPost/HttpPut/HttpHead表示Http的各種方法org.apacke.http包中主要類/接口說(shuō)明HttpResponse一個(gè)Http響應(yīng)StatusLine狀態(tài)行Header表示Http頭部字段HeaderElementHttp頭部值中的一個(gè)元素NameValuesPair封裝了屬性:值對(duì)的類HttpEntity一個(gè)可以同Http消息進(jìn)行接收或發(fā)送的實(shí)體3)其他包中主要類/接口說(shuō)明3、HTTP通信對(duì)于大部分應(yīng)用程序而言JDK本身提供的網(wǎng)絡(luò)功能已遠(yuǎn)遠(yuǎn)不夠,這時(shí)就需要Android提供的ApacheHttpClient了。它是一個(gè)開源項(xiàng)目,功能更加完善,為客戶端的Http編程提供高效、最新、功能豐富的工具包支持。通過(guò)Apache提供的http包工具進(jìn)行Http通信,兩種形式:GET和POST。Get和POST請(qǐng)求主要有幾種區(qū)別:1、Post請(qǐng)求可以向服務(wù)器傳送數(shù)據(jù),而且數(shù)據(jù)放在HTMLHEADER內(nèi)一起傳送到服務(wù)端URL地址,數(shù)據(jù)對(duì)用戶丌可見。而get是把參數(shù)數(shù)據(jù)隊(duì)列加到提交的URL中,值和表單內(nèi)各個(gè)字段一一對(duì)應(yīng)。2、get傳送的數(shù)據(jù)量較小,丌能大于2KB。post傳送的數(shù)據(jù)量較大,一般被默認(rèn)為丌受限制。3、get安全性非常低,post安全性較高。1、首先加入權(quán)限:<uses-permissionandroid:name="android.permission.INTERNET"/>2、新建HttpClient對(duì)象,并做超時(shí)時(shí)間設(shè)置:HttpClienthttpClient=newDefaultHttpClient();//新建HttpClient對(duì)象HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),3000);//設(shè)置連接超時(shí)HttpConnectionParams.setSoTimeout(httpClient.getParams(),3000);//設(shè)置數(shù)據(jù)讀取時(shí)間超時(shí)ConnManagerParams.setTimeout(httpClient.getParams(),3000);//設(shè)置從連接池中取連接超時(shí)3、使用Get請(qǐng)求,并獲取HttpResponse響應(yīng):HttpGethttpget=newHttpGet(url);//獲取請(qǐng)求HttpResponseresponse=httpClient.execute(httpget);//執(zhí)行請(qǐng)求,獲取響應(yīng)結(jié)果if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){//響應(yīng)通過(guò)Stringresult=EntityUtils.toString(response.getEntity(),"UTF-8");}//注意做異常處理3、HTTP通信4、使用Post請(qǐng)求,并獲取HttpResponse響應(yīng):HttpClienthttpClient=newDefaultHttpClient();//新建HttpClient對(duì)象HttpPosthttpPost=newHttpPost(url);//新建HttpPost對(duì)象List<NameValuePair>params=newArrayList<NameValuePair>();//使用NameValuePair來(lái)保存要傳遞的Post參數(shù)params.add(newBasicNameValuePair("username","hello"));//添加要傳遞的參數(shù)params.add(newBasicNameValuePair("password","eoe"));try{HttpEntityentity=newUrlEncodedFormEntity(params,HTTP.UTF_8);//設(shè)置字符集httpPost.setEntity(entity);//設(shè)置參數(shù)實(shí)體HttpResponsehttpResp=httpClient.execute(httpPost);//獲取HttpResponse實(shí)例if(httpResp.getStatusLine().getStatusCode()==HttpStatus.SC_OK){//響應(yīng)通過(guò)Stringresult=EntityUtils.toString(httpResp.getEntity(),"UTF-8");}else{ //響應(yīng)未通過(guò)}}catch{}3、HTTP通信然后介紹使用標(biāo)準(zhǔn)java接口進(jìn)行Http通信,分成兩種形式:GET和POST。1、其默認(rèn)使用get請(qǐng)求:URLpathUrl=newURL(url); //創(chuàng)建一個(gè)URL對(duì)象HttpURLConnectionurlConnect=(HttpURLConnection)pathUrl.openConnection(); //打開一個(gè)HttpURLConnection連接urlConnect.setConnectTimeout(3000); //設(shè)置連接超時(shí)時(shí)間urlConnect.connect();InputStreamReaderin=newInputStreamReader(urlConnect.getInputStream()); //得到讀取的內(nèi)容BufferedReaderbuffer=newBufferedReader(in); //為輸出創(chuàng)建BufferedReaderStringinputLine=null;while(((inputLine=buffer.readLine())!=null)){ //利用循環(huán)來(lái)讀取數(shù)據(jù)}3、HTTP通信2、使用post請(qǐng)求:Stringparams="username="+URLEncoder.encode("hello","UTF-8")+"&password="+URLEncoder.encode("eoe","UTF-8");byte[]postData=params.getBytes();URLpathUrl=newURL(url);//創(chuàng)建一個(gè)URL對(duì)象HttpURLConnectionurlConnect=(HttpURLConnection)pathUrl.openConnection();urlConnect.setConnectTimeout(3000);//設(shè)置連接超時(shí)時(shí)間urlConnect.setDoOutput(true);//post請(qǐng)求必須設(shè)置允許輸出urlConnect.setUseCaches(false);//post請(qǐng)求丌能使用緩存urlConnect.setRequestMethod("POST");//設(shè)置post方式請(qǐng)求urlConnect.setInstanceFollowRedirects(true);urlConnect.setRequestProperty("Content-Type","application/x-www-form-urlencode");//配置請(qǐng)求Content-TypeurlConnect.connect();//開始連接DataOutputStreamdos=newDataOutputStream(urlConnect.getOutputStream());//發(fā)送請(qǐng)求參數(shù)dos.write(postData);dos.flush();dos.close();if(urlConnect.getResponseCode()==200){//請(qǐng)求成功byte[]data=readInputStream(urlConnect.getInputStream());}3、HTTP通信4、Socket通信—什么是Socket

它實(shí)際上是網(wǎng)絡(luò)通信的一種接口,基于不同的協(xié)議,有各種不同的Socket,比如有基于TCP協(xié)議的Socket和基于UDP協(xié)議的Socket以及基于藍(lán)牙協(xié)議的Socket,Android中使用的是Java的Socket模型。Socket在計(jì)算機(jī)行業(yè)通常稱為”套接字“,用于描述IP地址和端口,是一個(gè)通信鏈的句柄。這是一個(gè)比較抽象的概念。計(jì)算機(jī)是擁有端口的,每一個(gè)端口都可以有一個(gè)應(yīng)用程序來(lái)進(jìn)行通訊的使用,比如:80端口是HTTP協(xié)議所使用的端口,21端口是FTP協(xié)議所使用的端口,端口是計(jì)算機(jī)和外界通訊的接口,這些接口都是邏輯的接口,端口號(hào)取值的范圍是零到256乘以256減1,1024以下的端口都是操作系統(tǒng)使用的保留端口,以上的端口我們可以自由的來(lái)使用,不要和其他應(yīng)用程序的端口沖突。應(yīng)用程序可以通過(guò)“套接字”向網(wǎng)絡(luò)發(fā)送請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)的請(qǐng)求,這時(shí)候就把Socket分成了兩部分,一部分是服務(wù)器端的Socket,這個(gè)Socket主要用來(lái)接收來(lái)自網(wǎng)絡(luò)的請(qǐng)求,它一直監(jiān)聽在某一個(gè)端口上。一部分是客戶端的Socket,這個(gè)Socket主要用來(lái)向網(wǎng)絡(luò)發(fā)送數(shù)據(jù)。Socket通訊模型UDP協(xié)議和TCP協(xié)議UDP協(xié)議和TCP協(xié)議是互聯(lián)網(wǎng)使用最廣的兩種協(xié)議,都是基于IP的協(xié)議。第一個(gè)區(qū)別是UDP協(xié)議是一個(gè)不太靠譜的協(xié)議,UDP協(xié)議把數(shù)據(jù)都打成數(shù)據(jù)包,數(shù)據(jù)包上自帶通訊地址,也就是說(shuō)我要把這個(gè)數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)上的哪一個(gè)地址,通過(guò)網(wǎng)絡(luò)把這個(gè)數(shù)據(jù)包發(fā)送出去,至于這個(gè)數(shù)據(jù)包是否發(fā)送到目的地,是否服務(wù)器端接收到了這個(gè)數(shù)據(jù)包,這個(gè)協(xié)議并不保證,就像中國(guó)的郵政,你是把信寄出去了,但是郵政系統(tǒng)不保證對(duì)方能收到你寄送的信。TCP發(fā)送數(shù)據(jù)的時(shí)候要求接收方接收到數(shù)據(jù)之后給一個(gè)回應(yīng),也就是你是否收到了,TCP可靠一些,當(dāng)我們發(fā)送一些比較重要的數(shù)據(jù)的時(shí)候一般都使用TCP協(xié)議。另外一個(gè)區(qū)別是UDP協(xié)議發(fā)送的一個(gè)數(shù)據(jù)包它的容量是有限的,而TCP協(xié)議則沒有這樣一個(gè)限制。并不是說(shuō)UDP協(xié)議一定就不如TCP協(xié)議,在不同的領(lǐng)域有不同的使用,UDP協(xié)議好處是速度相對(duì)快些。TCP協(xié)議相對(duì)慢些。Socket通訊流程創(chuàng)建服務(wù)端的步驟如下:1、指定端口實(shí)例化一個(gè)ServerSocket;2、調(diào)用ServerSocket的accept方法以在等待連接期間造成阻塞;3、獲取位于底層的Socket流以進(jìn)行讀寫操作;4、將數(shù)據(jù)封裝成流;5、對(duì)Socket進(jìn)行讀寫;6、關(guān)閉打開的流。創(chuàng)建客戶端的步驟如下:1、通過(guò)IP地址和端口實(shí)例化Socket,請(qǐng)求連接服務(wù)器;2、獲取Socket上的流以進(jìn)行讀寫;3、把流包裝進(jìn)輸入/輸出(比如:BufferedReader/PrintWriter戒者DataOutputStream/DataInputStream等)的實(shí)例;4、對(duì)Socket進(jìn)行讀寫;5、關(guān)閉打開的流。Socket與ServerSocketSocket是TCP/IP協(xié)議上的一種通信,在通信的兩端各建立一個(gè)Socket,從而在通信的兩端之間形成網(wǎng)絡(luò)虛擬鏈路。一旦建立了虛擬的網(wǎng)絡(luò)鏈路,兩端的程序就可以通過(guò)虛擬鏈路進(jìn)行通信。ClientA

發(fā)信息給ClientB,

A的信息首先發(fā)送信息到服務(wù)器Server,Server接受到信息后再把A的信息廣播發(fā)送給所有的Clients.首先要在服務(wù)器建立一個(gè)ServerSocket,ServerSocket對(duì)象用于監(jiān)聽來(lái)自客戶端的Socket連接,如果沒有連接,它將一直處于等待狀態(tài)。Socketaccept():如果接收到一個(gè)客戶端Socket的連接請(qǐng)求,該方法將返回一個(gè)與客戶端Socket對(duì)應(yīng)的SocketSocket與ServerSocketServer示例://創(chuàng)建一個(gè)ServerSocket,用于監(jiān)聽客戶端Socket的連接請(qǐng)求

ServerSocketss=newServerSocket(30000);//采用循環(huán)不斷接受來(lái)自客戶端的請(qǐng)求

while(true){//每當(dāng)接受到客戶端Socket的請(qǐng)求,服務(wù)器端也對(duì)應(yīng)產(chǎn)生一個(gè)SocketSockets=ss.accept();//下面就可以使用Socket進(jìn)行通信了...}客戶端通??墒褂肧ocket的構(gòu)造器來(lái)連接到指定服務(wù)器Client示例://創(chuàng)建連接到服務(wù)器、30000端口的SocketSockets=newSocket("14",30000);//下面就可以使用Socket進(jìn)行通信了...這樣Server和Client就可以進(jìn)行一個(gè)簡(jiǎn)單的通信了Socket通信模型基于TCP協(xié)議的Socket使用ServerSocket創(chuàng)建TCP服務(wù)器端服務(wù)器端編程步驟:1、創(chuàng)建服務(wù)器端套接字并綁定到一個(gè)端口上(0-1023是系統(tǒng)預(yù)留的,最好大于1024)

2、套接字設(shè)置監(jiān)聽模式等待連接請(qǐng)求

3、接受連接請(qǐng)求后進(jìn)行通信

4、返回,等待贏一個(gè)連接請(qǐng)求使用ServerSocket創(chuàng)建TCP服務(wù)器端ServerSocket類的對(duì)象用于監(jiān)聽來(lái)自客戶端的Socket連接,如果沒有連接,它將一直處于等待狀態(tài)。ServerSocket包含一個(gè)監(jiān)聽來(lái)自客戶端連接請(qǐng)求的方法。Socketaccept():如果接收到一個(gè)客戶端Socket的連接請(qǐng)求,該方法將返回一個(gè)與連接客戶端Socket對(duì)應(yīng)的Socket,否則該方法將一直處于等待狀態(tài),線程也被阻塞。通常情況下,服務(wù)器不應(yīng)該只接收一個(gè)客戶端請(qǐng)求,而應(yīng)該不斷地接收來(lái)自客戶端的所有請(qǐng)求。當(dāng)ServerSocket使用完畢后,應(yīng)使用ServerSocket的close()方法來(lái)關(guān)閉該ServerSocket。使用ServerSocket創(chuàng)建TCP服務(wù)器端為了創(chuàng)建ServerSocket對(duì)象,ServerSocket類提供以下及格構(gòu)造方法:ServerSocket(intport):用指定的端口port來(lái)創(chuàng)建一個(gè)ServerSocket,該端口應(yīng)該是一個(gè)有效的端口整數(shù)值0~65535.使用該構(gòu)造方法創(chuàng)建的ServerSocket沒有指定Ip地址,則該ServerSocket將會(huì)綁定到本機(jī)默認(rèn)的Ip地址。通常端口號(hào)推薦使用1024以上的端口,以避免與其他應(yīng)用程序的通用端口沖突。ServerSocket(int

port,int

backlog):增加一個(gè)用來(lái)改變連接隊(duì)列長(zhǎng)度的參數(shù)。ServerSocket(int

port,int

backlog,InetAddressaddr):在機(jī)器存在多個(gè)Ip地址的情況下,允許通過(guò)addr這個(gè)參數(shù)來(lái)指定將ServerSocket綁定到指定的Ip地址。由于手機(jī)無(wú)線上網(wǎng)的Ip地址通常是由移動(dòng)運(yùn)營(yíng)公司動(dòng)態(tài)分配的,一般不會(huì)有自己固定的Ip地址,因此很少在手機(jī)上運(yùn)行服務(wù)器端,服務(wù)器端通常運(yùn)行在有固定Ip的服務(wù)器上。使用Socket進(jìn)行通信客戶端編程步驟:

1、創(chuàng)建客戶端套接字(指定服務(wù)器端IP地址與端口號(hào))

2、連接(Android創(chuàng)建Socket時(shí)會(huì)自動(dòng)連接)

3、與服務(wù)器端進(jìn)行通信

4、關(guān)閉套接字使用Socket進(jìn)行通信Socket類常用的構(gòu)造方法:用服務(wù)器端的IP地址對(duì)象和端口號(hào)建立SocketpublicSocket(InetAddress

address,int

port):用服務(wù)器端的機(jī)器名和端口號(hào)建立SocketpublicSocket(String

host,int

port)例如:

//創(chuàng)建連接到本機(jī)、端口為8899的SocketSockets=newSocket(“39”,8899);//下面就可以使用Socket進(jìn)行通信了。。。。。。。。。。。。。。。說(shuō)明:當(dāng)程序執(zhí)行上面代碼時(shí),該代碼將會(huì)連接到指定服務(wù)器,讓服務(wù)器的ServerSocket的accept()方法向下執(zhí)行,于是服務(wù)器端和客戶端就產(chǎn)生一對(duì)互相連接的Socket。使用Socket進(jìn)行通信當(dāng)客戶端、服務(wù)器端產(chǎn)生了對(duì)應(yīng)的Socket之后,就通過(guò)Socket進(jìn)行通信。Socket提供如下兩個(gè)方法來(lái)獲取輸入流和輸出流。取得Socket對(duì)象的輸入流publicInputStreamgetInputStream():返回該Socket對(duì)象對(duì)應(yīng)的輸入流,讓程序通過(guò)該輸入流從Socket中取出數(shù)據(jù)。取得Socket對(duì)象的輸出流publicOutputStreamgetOutputStream():返回該Socket對(duì)象對(duì)應(yīng)的輸出流,讓程序通過(guò)該輸出流向Socket中輸出數(shù)據(jù)。關(guān)閉socketpublicvoidclose()throwsIOException示例服務(wù)器端:public

classSimpleServer{public

static

voidmain(String[]args)throwsIOException{System.out.println("Howareyou...");//創(chuàng)建一個(gè)ServerSocket,用于監(jiān)聽客戶端Socket的連接請(qǐng)求ServerSocketss=newServerSocket(20000);//采用循環(huán)不斷接受來(lái)自客戶端的請(qǐng)求while(true){//每當(dāng)接受到客戶端Socket的請(qǐng)求,服務(wù)器端也對(duì)應(yīng)產(chǎn)生一個(gè)SocketSockets=ss.accept();OutputStreamos=s.getOutputStream();os.write("Howareyou!\n".getBytes("utf-8"));//關(guān)閉輸出流,關(guān)閉Socketos.close();s.close();}}}示例客戶端:public

classSimpleClientextendsActivity{EditTextshow;public

voidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);show=(EditText)findViewById(R.id.show);try{Socketsocket=newSocket("39",20000);//將Socket對(duì)應(yīng)的輸入流包裝成BufferedReaderBufferedReaderbr=newBufferedReader(newInputStreamReader(socket.getInputStream()));Stringline=br.readLine();//進(jìn)行普通IO操作show.setText("來(lái)自服務(wù)器的數(shù)據(jù):"+line);br.close();socket.close();}catch(IOExceptione){e.printStackTrace();}}}布局main.xml:xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android=""android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><EditTextandroid:id="@+id/show"android:layout_width="fill_parent"android:layout_height="wrap_content"android:editable="false"android:cursorVisible="false"/></LinearLayout>示例說(shuō)明:android:cursorVisible屬性的作用:設(shè)定光標(biāo)為顯示/隱藏,默認(rèn)顯示。運(yùn)行效果圖:說(shuō)明:該android應(yīng)用需要訪問(wèn)互聯(lián)網(wǎng),因此還需要為該應(yīng)用賦予訪問(wèn)網(wǎng)絡(luò)的權(quán)限,即在項(xiàng)目清單文件中添加授權(quán)訪問(wèn)互聯(lián)網(wǎng)的權(quán)限:<uses-permissionandroid:name="android.permission.INTERNET"/>示例多線程實(shí)際應(yīng)用中的客戶端可能需要和服務(wù)器保持長(zhǎng)時(shí)間通信,即服務(wù)器需要不斷地讀取客戶端數(shù)據(jù),并想客戶端寫入數(shù)據(jù),客戶端也需要不斷地讀取服務(wù)器數(shù)據(jù),并向服務(wù)器寫入數(shù)據(jù)。使用傳統(tǒng)的BufferedReader的readLine方法讀取數(shù)據(jù)時(shí),在該方法成功返回之前,線程被阻塞,程序無(wú)法繼續(xù)執(zhí)行?;谶@個(gè)原因,服務(wù)器應(yīng)該為每個(gè)Socket單獨(dú)啟動(dòng)一條線程,每條線程負(fù)責(zé)與一個(gè)客戶端進(jìn)行通信。下面以一個(gè)簡(jiǎn)單C/S聊天室為例,來(lái)實(shí)現(xiàn)多個(gè)客戶端通信。多線程服務(wù)器端實(shí)現(xiàn)服務(wù)器端提供兩個(gè)類,一個(gè)是創(chuàng)建ServerSocket監(jiān)聽的主類,一個(gè)是負(fù)責(zé)處理每個(gè)Socket通信的線程類。多線程服務(wù)器端主類因?yàn)榉?wù)器端應(yīng)該包含多條線程,每個(gè)Socket對(duì)應(yīng)一條線程,該線程負(fù)責(zé)讀取Socket對(duì)應(yīng)輸入流的數(shù)據(jù)(即從客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù)),并將讀到的數(shù)據(jù)向每個(gè)Socket輸出來(lái)發(fā)送一遍(即將一個(gè)客戶端發(fā)送的數(shù)據(jù)廣播給其它的客戶端),因此需要在服務(wù)器端使用List來(lái)保存所有的Socket。另外讓服務(wù)器端只負(fù)責(zé)接收客戶端Socket的連接請(qǐng)求,每當(dāng)客戶端Socket連接到該ServerSocket之后,程序?qū)?duì)應(yīng)的Socket加入到List集合中,并為該Socket啟動(dòng)一條線程,該線程就負(fù)責(zé)處理該Socket的所有通信任務(wù)。(1)定義保存所有Socket的集合(2)創(chuàng)建ServerSocket監(jiān)聽(3)采用循環(huán)不斷接收來(lái)自客戶端的連接請(qǐng)求(4)將接收客戶端請(qǐng)求產(chǎn)生的Socket添加到集合中(5)客戶端連接后啟動(dòng)一條線程為該客戶端服務(wù)多線程//定義保存所有Socket的ArrayListpublic

staticArrayList<Socket>socketList=newArrayList<Socket>();

public

static

voidmain(String[]args)throwsIOException{ServerSocketss=newServerSocket(30000);while(true){//此行代碼會(huì)阻塞,將一直等待別人的連接Sockets=ss.accept();socketList.add(s);//每當(dāng)客戶端連接后啟動(dòng)一條ServerThread線程為該客戶端服務(wù)newThread(newServerThread(s)).start();}}多線程服務(wù)器端線程類服務(wù)器端線程類不斷讀取客戶端的數(shù)據(jù),在此聲明一個(gè)方法來(lái)讀取客戶端的數(shù)據(jù),當(dāng)服務(wù)器線程類讀取到客戶端的數(shù)據(jù)之后,程序遍歷Socket集合,并將該數(shù)據(jù)向集合中的每一個(gè)Socket發(fā)送一次。如果讀取數(shù)據(jù)過(guò)程中捕獲到IOException異常,則表明該Socket對(duì)應(yīng)的客戶端Socket出現(xiàn)了問(wèn)題,程序就將該Socket從集合中刪除。

多線程(1)定義當(dāng)前線程所處理的Socket及Socket所對(duì)應(yīng)的輸入流//定義當(dāng)前線程所處理的SocketSockets=null;//該線程所處理的Socket所對(duì)應(yīng)的輸入流BufferedReaderbr=null;(2)聲明構(gòu)造器,并初始化該Socket對(duì)應(yīng)的輸入流publicServerThread(Sockets)throwsIOException{this.s=s;//初始化該Socket對(duì)應(yīng)的輸入流br=newBufferedReader(newInputStreamReader(s.getInputStream(),"utf-8"));}(4)定義讀取客戶端數(shù)據(jù)的方法(5)重寫run方法,將把從Socket中讀到的數(shù)據(jù)向集合中的每一個(gè)Socket轉(zhuǎn)發(fā)一遍多線程(3)定義讀取客戶端數(shù)據(jù)的方法privateStringreadFromClient(){try{returnbr.readLine();}catch(IOExceptione){////如果捕捉到異常,表明該Socket對(duì)應(yīng)的客戶端已經(jīng)關(guān)閉,刪除該Socket。MyServer.socketList.remove(s);}return

null;}(4)重寫run方法,將把從Socket中讀到的數(shù)據(jù)向集合中的每一個(gè)Socket轉(zhuǎn)發(fā)一遍public

voidrun(){Stringcontent=null;//采用循環(huán)不斷從Socket中讀取客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù)while((content=readFromClient())!=null){//遍歷socketList中的每個(gè)Socket,并將讀到的內(nèi)容向每個(gè)Socket發(fā)送一次for(Sockets:MyServer.socketList){OutputStreamos=s.getOutputStream();os.write((content+"\n").getBytes("utf-8"));}}}多線程客戶端實(shí)現(xiàn)

每個(gè)客戶端應(yīng)該包含兩條線程:一條負(fù)責(zé)生存主界面,并響應(yīng)用戶動(dòng)作,并將用戶輸入的數(shù)據(jù)寫入Socket對(duì)應(yīng)的輸出流中;另一條負(fù)責(zé)讀取Socket對(duì)應(yīng)輸入流中的數(shù)據(jù)(從服務(wù)器發(fā)送過(guò)來(lái)的數(shù)據(jù)),并負(fù)責(zé)將這些數(shù)據(jù)在程序主界面上顯示處理。多線程布局main.xml<LinearLayoutandroid:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"><EditTextandroid:id="@+id/input"android:layout_width="240px"android:layout_height="wrap_content"/><Buttonandroid:id="@+id/send"android:layout_width="fill_parent"android:layout_height="wrap_content"android:paddingLeft="8px"android:text="發(fā)送"/></LinearLayout><EditTextandroid:id="@+id/show"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="top"android:editable="false"android:cursorVisible="false"/>多線程客戶端端主類

客戶端的Activity負(fù)責(zé)生成程序主界面,并為程序的按鈕單擊事件綁定監(jiān)聽器,當(dāng)用戶單擊按鈕時(shí)向服務(wù)器發(fā)送信息。(1)聲明控件對(duì)象、輸出來(lái)對(duì)象和Handler對(duì)象EditTextinput,show;Buttonsend;OutputStreamos;Handlerhandler;多線程(2)獲取控件實(shí)例及聲明Socket對(duì)象

input=(EditText)findViewById(R.id.input);show=(EditText)findViewById(R.id.show);send=(Button)findViewById(R.id.send);Socketsocket;(3)Android不允許子線程訪問(wèn)界面組件,定義一個(gè)handler來(lái)處理來(lái)自子線程的消息handler=newHandler(){public

voidhandleMessage(Messagemsg){//如果消息來(lái)自于子線程if(msg.what==0x123){//將讀取的內(nèi)容追加顯示在文本框中show.append("\n"+msg.obj.toString());}}};多線程(4)建立Socket,與ServerSocket建立連接,并啟動(dòng)客戶端線程不斷讀取來(lái)自服務(wù)器端的數(shù)據(jù)

s=newSocket("39",30000);//客戶端啟動(dòng)ClientThread線程不斷讀取來(lái)自服務(wù)器的數(shù)據(jù)newThread(newClientThread(s,handler)).start();os=s.getOutputStream();(5)為發(fā)送按鈕添加事件,將用戶在文本框內(nèi)輸入的內(nèi)容寫入網(wǎng)絡(luò),然后清空input文本框

send.setOnClickListener(newOnClickListener(){ publicvoidonClick(Viewv){//將用戶在文本框內(nèi)輸入的內(nèi)容寫入網(wǎng)絡(luò)os.write((input.getText().toString()+"\r\n").getBytes("utf-8"));//清空input文本框input.setText(""); }});多線程程序的子線程負(fù)責(zé)讀取來(lái)自網(wǎng)絡(luò)的數(shù)據(jù),讀到數(shù)據(jù)之后便通過(guò)Handler對(duì)象發(fā)送一條消息。(1)聲明該線程負(fù)責(zé)處理的Socket以及該線程處理的Socket所對(duì)應(yīng)的輸入流//該線程負(fù)責(zé)處理的SocketprivateSockets;privateHandlerhandler;//該線程所處理的Socket所對(duì)應(yīng)的輸入流BufferedReaderbr=null;(2)定義構(gòu)造器publicClientThread(Sockets,Handlerhandler)throwsIOException{this.s=s;this.handler=handler;br=newBufferedReader(newInputStreamReader(s.getInputStream()));}多線程(3)不斷讀取Socket輸入的內(nèi)容public

voidrun(){Stringcontent=null;while((content=br.readLine())!=null){//每當(dāng)讀到來(lái)自服務(wù)器的數(shù)據(jù)之后,發(fā)送消息通知程序界面顯示該數(shù)據(jù)Messagemsg=newMessage();msg.what=0x123;msg.obj=content;handler.sendMessage(msg);}}WebViewWebView是一個(gè)開發(fā)的瀏覽器組件,是基于WebKit內(nèi)核開發(fā)出來(lái)的,如Safari、GoogleChrome瀏覽器都是通過(guò)WebView實(shí)現(xiàn)的,而在Android系統(tǒng)中,默認(rèn)提供了WebView組件的支持。除了支持各個(gè)瀏覽器的“前進(jìn)”、“后退”等功能之外,最為強(qiáng)大的是在WebView組件之中也支持JavaScript的操作。

Webview瀏覽網(wǎng)頁(yè)Webview的用法與普通ImageView用法基本類似,它提供了大量方法來(lái)執(zhí)行瀏覽器操作,例如如下常用方法:clearCache(booleanincludeDiskFiles)//清除緩存clearHistory()//清除歷史前進(jìn)和后退getSettings()//獲取WebSettinggoBack()//返回上一頁(yè)面goForward()//前一頁(yè)面loadUrl(Stringurl)//打開一個(gè)頁(yè)面reload()//重新加載當(dāng)前頁(yè)面stopLoading()//停止加載setScrollBarStyle(intstyle)//指定loadData("HTMLString")//加載HTML

默認(rèn)情況下WebView不支持javascript,和ajax效果:如下可以啟用javascript和Ajax:WebSettings

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論