一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Socket 通信原理(Android客戶端和服務器以TCP&&UDP方式互通)

 看風景D人 2014-09-01


ZERO、前言

有關通信原理內容是在網(wǎng)上或百科整理得到,代碼部分為本人所寫,如果不當,還望指教。



一、Socket通信簡介 

Android與服務器的通信方式主要有兩種,一是Http通信,一是Socket通信。兩者的最大差異在于,http連接使用的是“請求—響應方式”,即在請求時建立連接通道,當客戶端向服務器發(fā)送請求后,服務器端才能向客戶端返回數(shù)據(jù)。而Socket通信則是在雙方建立起連接后就可以直接進行數(shù)據(jù)的傳輸,在連接時可實現(xiàn)信息的主動推送,而不需要每次由客戶端想服務器發(fā)送請求。 那么,什么是socket?Socket又稱套接字,在程序內部提供了與外界通信的端口,即端口通信。通過建立socket連接,可為通信雙方的數(shù)據(jù)傳輸傳提供通道。socket的主要特點有數(shù)據(jù)丟失率低,使用簡單且易于移植。


1.1什么是Socket Socket
是一種抽象層,應用程序通過它來發(fā)送和接收數(shù)據(jù),使用Socket可以將應用程序添加到網(wǎng)絡中,與處于同一網(wǎng)絡中的其他應用程序進行通信。簡單來說,Socket提供了程序內部與外界通信的端口并為通信雙方的提供了數(shù)據(jù)傳輸通道。


 1.2Socket的分類
 根據(jù)不同的的底層協(xié)議,Socket的實現(xiàn)是多樣化的。本指南中只介紹TCP/IP協(xié)議族的內容,在這個協(xié)議族當中主要的Socket類型為流套接字(streamsocket)和數(shù)據(jù)報套接字(datagramsocket)。流套接字將TCP作為其端對端協(xié)議,提供了一個可信賴的字節(jié)流服務。數(shù)據(jù)報套接字使用UDP協(xié)議,提供數(shù)據(jù)打包發(fā)送服務。 下面,我們來認識一下這兩種Socket類型的基本實現(xiàn)模型。


二、Socket 基本通信模型



三、Socket基本實現(xiàn)原理


 3.1基于TCP協(xié)議的Socket 
服務器端首先聲明一個ServerSocket對象并且指定端口號,然后調用Serversocket的accept()方法接收客戶端的數(shù)據(jù)。accept()方法在沒有數(shù)據(jù)進行接收的處于堵塞狀態(tài)。(Socketsocket=serversocket.accept()),一旦接收到數(shù)據(jù),通過inputstream讀取接收的數(shù)據(jù)。
  客戶端創(chuàng)建一個Socket對象,指定服務器端的ip地址和端口號(Socketsocket=newSocket("172.168.10.108",8080);),通過inputstream讀取數(shù)據(jù),獲取服務器發(fā)出的數(shù)據(jù)(OutputStreamoutputstream=socket.getOutputStream()),最后將要發(fā)送的數(shù)據(jù)寫入到outputstream即可進行TCP協(xié)議的socket數(shù)據(jù)傳輸。
3.2基于UDP協(xié)議的數(shù)據(jù)傳輸 
服務器端首先創(chuàng)建一個DatagramSocket對象,并且指點監(jiān)聽的端口。接下來創(chuàng)建一個空的DatagramSocket對象用于接收數(shù)據(jù)(bytedata[]=newbyte[1024;]DatagramSocketpacket=newDatagramSocket(data,data.length)),使用DatagramSocket的receive方法接收客戶端發(fā)送的數(shù)據(jù),receive()與serversocket的accepet()類似,在沒有數(shù)據(jù)進行接收的處于堵塞狀態(tài)。
客戶端也創(chuàng)建個DatagramSocket對象,并且指點監(jiān)聽的端口。接下來創(chuàng)建一個InetAddress對象,這個對象類似與一個網(wǎng)絡的發(fā)送地址(InetAddressserveraddress=InetAddress.getByName("172.168.1.120")).定義要發(fā)送的一個字符串,創(chuàng)建一個DatagramPacket對象,并制定要講這個數(shù)據(jù)報包發(fā)送到網(wǎng)絡的那個地址以及端口號,最后使用DatagramSocket的對象的send()發(fā)送數(shù)據(jù)。*(Stringstr="hello";bytedata[]=str.getByte();DatagramPacketpacket=new DatagramPacket(data,data.length,serveraddress,4567);socket.send(packet);)


四、android 實現(xiàn)socket簡單通信

前言:添加權限

  1. <!--允許應用程序改變網(wǎng)絡狀態(tài)-->    
  2. <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>    
  3.     
  4. <!--允許應用程序改變WIFI連接狀態(tài)-->    
  5. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>    
  6.     
  7. <!--允許應用程序訪問有關的網(wǎng)絡信息-->    
  8. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>    
  9.     
  10. <!--允許應用程序訪問WIFI網(wǎng)卡的網(wǎng)絡信息-->    
  11. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>    
  12.     
  13. <!--允許應用程序完全使用網(wǎng)絡-->    
  14. <uses-permission android:name="android.permission.INTERNET"/>    

4.1使用TCP協(xié)議通信

android端實現(xiàn):

  1.     protected void connectServerWithTCPSocket() {  
  2.   
  3.         Socket socket;  
  4.         try {// 創(chuàng)建一個Socket對象,并指定服務端的IP及端口號  
  5.             socket = new Socket("192.168.1.32", 1989);  
  6.             // 創(chuàng)建一個InputStream用戶讀取要發(fā)送的文件。  
  7.             InputStream inputStream = new FileInputStream("e://a.txt");  
  8.             // 獲取Socket的OutputStream對象用于發(fā)送數(shù)據(jù)。  
  9.             OutputStream outputStream = socket.getOutputStream();  
  10.             // 創(chuàng)建一個byte類型的buffer字節(jié)數(shù)組,用于存放讀取的本地文件  
  11.             byte buffer[] = new byte[4 * 1024];  
  12.             int temp = 0;  
  13.             // 循環(huán)讀取文件  
  14.             while ((temp = inputStream.read(buffer)) != -1) {  
  15.                 // 把數(shù)據(jù)寫入到OuputStream對象中  
  16.                 outputStream.write(buffer, 0, temp);  
  17.             }  
  18.             // 發(fā)送讀取的數(shù)據(jù)到服務端  
  19.             outputStream.flush();  
  20.   
  21.             /** 或創(chuàng)建一個報文,使用BufferedWriter寫入,看你的需求 **/  
  22. //          String socketData = "[2143213;21343fjks;213]";  
  23. //          BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(  
  24. //                  socket.getOutputStream()));  
  25. //          writer.write(socketData.replace("\n", " ") + "\n");  
  26. //          writer.flush();  
  27.             /************************************************/  
  28.         } catch (UnknownHostException e) {  
  29.             e.printStackTrace();  
  30.         } catch (IOException e) {  
  31.             e.printStackTrace();  
  32.         }  
  33.   
  34.     }  

服務器端簡單實現(xiàn):

  1. public void ServerReceviedByTcp() {  
  2.     // 聲明一個ServerSocket對象  
  3.     ServerSocket serverSocket = null;  
  4.     try {  
  5.         // 創(chuàng)建一個ServerSocket對象,并讓這個Socket在1989端口監(jiān)聽  
  6.         serverSocket = new ServerSocket(1989);  
  7.         // 調用ServerSocket的accept()方法,接受客戶端所發(fā)送的請求,  
  8.         // 如果客戶端沒有發(fā)送數(shù)據(jù),那么該線程就停滯不繼續(xù)  
  9.         Socket socket = serverSocket.accept();  
  10.         // 從Socket當中得到InputStream對象  
  11.         InputStream inputStream = socket.getInputStream();  
  12.         byte buffer[] = new byte[1024 * 4];  
  13.         int temp = 0;  
  14.         // 從InputStream當中讀取客戶端所發(fā)送的數(shù)據(jù)  
  15.         while ((temp = inputStream.read(buffer)) != -1) {  
  16.             System.out.println(new String(buffer, 0, temp));  
  17.         }  
  18.         serverSocket.close();  
  19.     } catch (IOException e) {  
  20.         e.printStackTrace();  
  21.     }  
  22. }  

4.2使用UDP協(xié)議通信

客戶端發(fā)送數(shù)據(jù)實現(xiàn):

  1. protected void connectServerWithUDPSocket() {  
  2.       
  3.     DatagramSocket socket;  
  4.     try {  
  5.         //創(chuàng)建DatagramSocket對象并指定一個端口號,注意,如果客戶端需要接收服務器的返回數(shù)據(jù),  
  6.         //還需要使用這個端口號來receive,所以一定要記住  
  7.         socket = new DatagramSocket(1985);  
  8.         //使用InetAddress(Inet4Address).getByName把IP地址轉換為網(wǎng)絡地址    
  9.         InetAddress serverAddress = InetAddress.getByName("192.168.1.32");  
  10.         //Inet4Address serverAddress = (Inet4Address) Inet4Address.getByName("192.168.1.32");    
  11.         String str = "[2143213;21343fjks;213]";//設置要發(fā)送的報文    
  12.         byte data[] = str.getBytes();//把字符串str字符串轉換為字節(jié)數(shù)組    
  13.         //創(chuàng)建一個DatagramPacket對象,用于發(fā)送數(shù)據(jù)。    
  14.         //參數(shù)一:要發(fā)送的數(shù)據(jù)  參數(shù)二:數(shù)據(jù)的長度  參數(shù)三:服務端的網(wǎng)絡地址  參數(shù)四:服務器端端口號   
  15.         DatagramPacket packet = new DatagramPacket(data, data.length ,serverAddress ,10025);    
  16.         socket.send(packet);//把數(shù)據(jù)發(fā)送到服務端。    
  17.     } catch (SocketException e) {  
  18.         e.printStackTrace();  
  19.     } catch (UnknownHostException e) {  
  20.         e.printStackTrace();  
  21.     } catch (IOException e) {  
  22.         e.printStackTrace();  
  23.     }    
  24. }  

客戶端接收服務器返回的數(shù)據(jù):

  1. public void ReceiveServerSocketData() {  
  2.     DatagramSocket socket;  
  3.     try {  
  4.         //實例化的端口號要和發(fā)送時的socket一致,否則收不到data  
  5.         socket = new DatagramSocket(1985);  
  6.         byte data[] = new byte[4 * 1024];  
  7.         //參數(shù)一:要接受的data 參數(shù)二:data的長度  
  8.         DatagramPacket packet = new DatagramPacket(data, data.length);  
  9.         socket.receive(packet);  
  10.         //把接收到的data轉換為String字符串  
  11.         String result = new String(packet.getData(), packet.getOffset(),  
  12.                 packet.getLength());  
  13.         socket.close();//不使用了記得要關閉  
  14.         System.out.println("the number of reveived Socket is  :" + flag  
  15.                 + "udpData:" + result);  
  16.     } catch (SocketException e) {  
  17.         e.printStackTrace();  
  18.     } catch (IOException e) {  
  19.         e.printStackTrace();  
  20.     }  
  21. }  

服務器接收客戶端實現(xiàn):

  1. public void ServerReceviedByUdp(){  
  2.     //創(chuàng)建一個DatagramSocket對象,并指定監(jiān)聽端口。(UDP使用DatagramSocket)    
  3.     DatagramSocket socket;  
  4.     try {  
  5.         socket = new DatagramSocket(10025);  
  6.         //創(chuàng)建一個byte類型的數(shù)組,用于存放接收到得數(shù)據(jù)    
  7.         byte data[] = new byte[4*1024];    
  8.         //創(chuàng)建一個DatagramPacket對象,并指定DatagramPacket對象的大小    
  9.         DatagramPacket packet = new DatagramPacket(data,data.length);    
  10.         //讀取接收到得數(shù)據(jù)    
  11.         socket.receive(packet);    
  12.         //把客戶端發(fā)送的數(shù)據(jù)轉換為字符串。    
  13.         //使用三個參數(shù)的String方法。參數(shù)一:數(shù)據(jù)包 參數(shù)二:起始位置 參數(shù)三:數(shù)據(jù)包長    
  14.         String result = new String(packet.getData(),packet.getOffset() ,packet.getLength());    
  15.     } catch (SocketException e) {  
  16.         e.printStackTrace();  
  17.     } catch (IOException e) {  
  18.         e.printStackTrace();  
  19.     }    
  20. }  


五、總結:

使用UDP方式android端和服務器端接收可以看出,其實android端和服務器端的發(fā)送和接收大庭相徑,只要端口號正確了,相互通信就沒有問題,TCP使用的是流的方式發(fā)送,UDP是以包的形式發(fā)送。



demo地址:http://download.csdn.net/detail/mad1989/5626975


20130621


    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    东京热男人的天堂一二三区| 少妇福利视频一区二区| 四十女人口红哪个色好看| 人妻熟女欲求不满一区二区| 欧美日韩一区二区三区色拉拉| 国产内射一级一片内射高清| 亚洲中文字幕视频在线播放 | 日韩欧美一区二区久久婷婷| 亚洲欧美日本国产有色| 久久99这里只精品热在线| 成人午夜在线视频观看| 中文字日产幕码三区国产| 国产欧美韩日一区二区三区| 少妇丰满a一区二区三区| 日韩中文无线码在线视频| 在线日韩欧美国产自拍| 欧美日韩一区二区综合| 91人妻久久精品一区二区三区| 亚洲国产精品久久精品成人| 青青操精品视频在线观看| 日韩欧美国产精品自拍| 久久99精品国产麻豆婷婷洗澡 | 丰满少妇高潮一区二区| 亚洲中文字幕视频在线观看| 亚洲中文字幕有码在线观看| 后入美臀少妇一区二区| 制服丝袜美腿美女一区二区| 久久热这里只有精品视频| 日韩高清中文字幕亚洲| 台湾综合熟女一区二区| 人妻一区二区三区在线| 色综合久久中文综合网| 国产精品久久三级精品| 欧美特色特黄一级大黄片| 国产精品欧美一区二区三区不卡| 国产在线一区中文字幕| 神马午夜福利一区二区| 免费精品一区二区三区| 国产黄色高清内射熟女视频| 老司机精品在线你懂的| 国产欧美日韩精品一区二|