Android開發(fā)中Socket通信的基本實(shí)現(xiàn)方法講解
一、Socket通信簡介
Android與服務(wù)器的通信方式主要有兩種,一是Http通信,一是Socket通信。兩者的最大差異在于,http連接使用的是“請求—響應(yīng)方式”,即在請求時建立連接通道,當(dāng)客戶端向服務(wù)器發(fā)送請求后,服務(wù)器端才能向客戶端返回?cái)?shù)據(jù)。而Socket通信則是在雙方建立起連接后就可以直接進(jìn)行數(shù)據(jù)的傳輸,在連接時可實(shí)現(xiàn)信息的主動推送,而不需要每次由客戶端想服務(wù)器發(fā)送請求。 那么,什么是socket?Socket又稱套接字,在程序內(nèi)部提供了與外界通信的端口,即端口通信。通過建立socket連接,可為通信雙方的數(shù)據(jù)傳輸傳提供通道。socket的主要特點(diǎn)有數(shù)據(jù)丟失率低,使用簡單且易于移植。
1.1什么是Socket Socket
是一種抽象層,應(yīng)用程序通過它來發(fā)送和接收數(shù)據(jù),使用Socket可以將應(yīng)用程序添加到網(wǎng)絡(luò)中,與處于同一網(wǎng)絡(luò)中的其他應(yīng)用程序進(jìn)行通信。簡單來說,Socket提供了程序內(nèi)部與外界通信的端口并為通信雙方的提供了數(shù)據(jù)傳輸通道。
1.2Socket的分類
根據(jù)不同的的底層協(xié)議,Socket的實(shí)現(xiàn)是多樣化的。本指南中只介紹TCP/IP協(xié)議族的內(nèi)容,在這個協(xié)議族當(dāng)中主要的Socket類型為流套接字(streamsocket)和數(shù)據(jù)報套接字(datagramsocket)。流套接字將TCP作為其端對端協(xié)議,提供了一個可信賴的字節(jié)流服務(wù)。數(shù)據(jù)報套接字使用UDP協(xié)議,提供數(shù)據(jù)打包發(fā)送服務(wù)。 下面,我們來認(rèn)識一下這兩種Socket類型的基本實(shí)現(xiàn)模型。
二、Socket 基本通信模型

三、Socket基本實(shí)現(xiàn)原理
3.1基于TCP協(xié)議的Socket
服務(wù)器端首先聲明一個ServerSocket對象并且指定端口號,然后調(diào)用Serversocket的accept()方法接收客戶端的數(shù)據(jù)。accept()方法在沒有數(shù)據(jù)進(jìn)行接收的處于堵塞狀態(tài)。(Socketsocket=serversocket.accept()),一旦接收到數(shù)據(jù),通過inputstream讀取接收的數(shù)據(jù)。
客戶端創(chuàng)建一個Socket對象,指定服務(wù)器端的ip地址和端口號(Socketsocket=newSocket("172.168.10.108",8080);),通過inputstream讀取數(shù)據(jù),獲取服務(wù)器發(fā)出的數(shù)據(jù)(OutputStreamoutputstream=socket.getOutputStream()),最后將要發(fā)送的數(shù)據(jù)寫入到outputstream即可進(jìn)行TCP協(xié)議的socket數(shù)據(jù)傳輸。
3.2基于UDP協(xié)議的數(shù)據(jù)傳輸
服務(wù)器端首先創(chuàng)建一個DatagramSocket對象,并且指點(diǎn)監(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ù)進(jìn)行接收的處于堵塞狀態(tài)。
客戶端也創(chuàng)建個DatagramSocket對象,并且指點(diǎn)監(jiān)聽的端口。接下來創(chuàng)建一個InetAddress對象,這個對象類似與一個網(wǎng)絡(luò)的發(fā)送地址(InetAddressserveraddress=InetAddress.getByName("172.168.1.120")).定義要發(fā)送的一個字符串,創(chuàng)建一個DatagramPacket對象,并制定要講這個數(shù)據(jù)報包發(fā)送到網(wǎng)絡(luò)的那個地址以及端口號,最后使用DatagramSocket的對象的send()發(fā)送數(shù)據(jù)。*(Stringstr="hello";bytedata[]=str.getByte();DatagramPacketpacket=new DatagramPacket(data,data.length,serveraddress,4567);socket.send(packet);)
三、Android上最簡單的socket通信實(shí)現(xiàn)示例
服務(wù)器程序
服務(wù)器程序需要在PC上運(yùn)行,該程序比較的簡單,因此不需要建立Android項(xiàng)目,直接定義一個JAVA類,并且運(yùn)行該類即可。它僅僅建立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)不斷接受來自客戶端的請求,服務(wù)器端也對應(yīng)產(chǎn)生一個Socket
while(true){
Socket s=ss.accept();
OutputStream os=s.getOutputStream();
os.write("您好,您收到了服務(wù)器的新年祝福!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("自己計(jì)算機(jī)的IP地址", 30000);
//設(shè)置10秒之后即認(rèn)為是超時
socket.setSoTimeout(10000);
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String line = br.readLine();
show.setText("來自服務(wù)器的數(shù)據(jù):"+line);
br.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
Log.e("UnknownHost", "來自服務(wù)器的數(shù)據(jù)");
e.printStackTrace();
} catch (IOException e) {
Log.e("IOException", "來自服務(wù)器的數(shù)據(jù)");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
需要注意的是,在Manifest.xml文件當(dāng)中,需要對互聯(lián)網(wǎng)的訪問進(jìn)行授權(quán)。
<uses-permission android:name="android.permission.INTERNET"/>
- Android Socket通信詳解
- Android編程之客戶端通過socket與服務(wù)器通信的方法
- Android中Socket通信的實(shí)現(xiàn)方法概述
- python服務(wù)器與android客戶端socket通信實(shí)例
- android利用websocket協(xié)議與服務(wù)器通信
- Android中使用socket通信實(shí)現(xiàn)消息推送的方法詳解
- 詳解Android 基于TCP和UDP協(xié)議的Socket通信
- Android Socket通信實(shí)現(xiàn)簡單聊天室
- Android中socket通信的簡單實(shí)現(xiàn)
- Android Socket通信的簡單實(shí)現(xiàn)
相關(guān)文章
詳解spring boot starter redis配置文件
spring-boot-starter-Redis主要是通過配置RedisConnectionFactory中的相關(guān)參數(shù)去實(shí)現(xiàn)連接redis service。下面通過本文給大家介紹在spring boot的配置文件中redis的基本配置,需要的的朋友參考下2017-07-07
Spring Boot整合tk.mybatis代碼實(shí)例
這篇文章主要介紹了Spring Boot整合tk.mybatis代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11
Java中SpringBoot的@Transactional原理
這篇文章主要介紹了Java中SpringBoot的@Transactional原理,面向元數(shù)據(jù)遍歷已經(jīng)成為越來越多開發(fā)者的偏好,因此原理從Springboot的EnableTransactionManagement注解說起,需要的朋友可以參考下2023-07-07
Java?Stream對象并行處理方法parallel()代碼示例
在Java中Stream是一種用于處理集合數(shù)據(jù)的流式操作API,它提供了一種簡潔、靈活、高效的方式來對集合進(jìn)行各種操作,下面這篇文章主要給大家介紹了關(guān)于Java?Stream對象并行處理方法parallel()的相關(guān)資料,需要的朋友可以參考下2023-11-11
Java使用FutureTask實(shí)現(xiàn)預(yù)加載的示例詳解
基于FutureTask的特性,通常可以使用FutureTask做一些預(yù)加載工作,比如一些時間較長的計(jì)算等,本文就來和大家講講具體實(shí)現(xiàn)方法吧,感興趣的可以了解一下2023-06-06

