Android開發(fā)中Socket通信的基本實現(xiàn)方法講解
一、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上最簡單的socket通信實現(xiàn)示例
服務器程序
服務器程序需要在PC上運行,該程序比較的簡單,因此不需要建立Android項目,直接定義一個JAVA類,并且運行該類即可。它僅僅建立ServerSocket監(jiān)聽,并使用Socket獲取輸入輸出流。
import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class SimpleServer { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //創(chuàng)建一個ServerSocket,用于監(jiān)聽客戶端socket的連接請求 ServerSocket ss=new ServerSocket(30000); //采用循環(huán)不斷接受來自客戶端的請求,服務器端也對應產(chǎn)生一個Socket while(true){ Socket s=ss.accept(); OutputStream os=s.getOutputStream(); os.write("您好,您收到了服務器的新年祝福!n".getBytes("utf-8")); os.close(); s.close(); } }}
客戶端程序
package my.learn.tcp; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.net.UnknownHostException; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.EditText; public class SimpleClient extends Activity { private EditText show; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.main); show = (EditText) findViewById(R.id.show); try { Socket socket = new Socket("自己計算機的IP地址", 30000); //設置10秒之后即認為是超時 socket.setSoTimeout(10000); BufferedReader br = new BufferedReader(new InputStreamReader( socket.getInputStream())); String line = br.readLine(); show.setText("來自服務器的數(shù)據(jù):"+line); br.close(); socket.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block Log.e("UnknownHost", "來自服務器的數(shù)據(jù)"); e.printStackTrace(); } catch (IOException e) { Log.e("IOException", "來自服務器的數(shù)據(jù)"); // TODO Auto-generated catch block e.printStackTrace(); } } }
需要注意的是,在Manifest.xml文件當中,需要對互聯(lián)網(wǎng)的訪問進行授權。
<uses-permission android:name="android.permission.INTERNET"/>
相關文章
詳解spring boot starter redis配置文件
spring-boot-starter-Redis主要是通過配置RedisConnectionFactory中的相關參數(shù)去實現(xiàn)連接redis service。下面通過本文給大家介紹在spring boot的配置文件中redis的基本配置,需要的的朋友參考下2017-07-07Java中SpringBoot的@Transactional原理
這篇文章主要介紹了Java中SpringBoot的@Transactional原理,面向元數(shù)據(jù)遍歷已經(jīng)成為越來越多開發(fā)者的偏好,因此原理從Springboot的EnableTransactionManagement注解說起,需要的朋友可以參考下2023-07-07Java?Stream對象并行處理方法parallel()代碼示例
在Java中Stream是一種用于處理集合數(shù)據(jù)的流式操作API,它提供了一種簡潔、靈活、高效的方式來對集合進行各種操作,下面這篇文章主要給大家介紹了關于Java?Stream對象并行處理方法parallel()的相關資料,需要的朋友可以參考下2023-11-11Java使用FutureTask實現(xiàn)預加載的示例詳解
基于FutureTask的特性,通??梢允褂肍utureTask做一些預加載工作,比如一些時間較長的計算等,本文就來和大家講講具體實現(xiàn)方法吧,感興趣的可以了解一下2023-06-06