Android網(wǎng)絡(luò)編程之UDP通信模型實(shí)例
什么是Android UDP?
UDP是User Datagram Protocol的簡(jiǎn)稱,中文名是用戶數(shù)據(jù)包協(xié)議,是OSI參考模型中一種無(wú)連接的傳輸層協(xié)議,提供面向事務(wù)的簡(jiǎn)單不可靠信息傳送服務(wù)。它是IETF RFC 768是UDP的正式規(guī)范。在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包。在OSI模型中,在第四層-傳輸層,處于IP協(xié)議的上一層。UDP有不提供數(shù)據(jù)報(bào)分組、組裝和不能對(duì)數(shù)據(jù)包的排序的缺點(diǎn),也就是說(shuō),當(dāng)報(bào)文發(fā)送之后,是無(wú)法得知其是否安全完整到達(dá)的。UDP用來(lái)支持那些需要在計(jì)算機(jī)之間傳輸數(shù)據(jù)的網(wǎng)絡(luò)應(yīng)用。包括網(wǎng)絡(luò)視頻會(huì)議系統(tǒng)在內(nèi)的眾多的客戶/服務(wù)器模式的網(wǎng)絡(luò)應(yīng)用都需要使用UDP協(xié)議。UDP協(xié)議從問(wèn)世至今已經(jīng)被使用了很多年,雖然其最初的光彩已經(jīng)被一些類似協(xié)議所掩蓋,但是即使是在今天,UDP仍然不失為一項(xiàng)非常實(shí)用和可行的網(wǎng)絡(luò)傳輸層協(xié)議。
與所熟知的TCP(傳輸控制協(xié)議)協(xié)議一樣,UDP協(xié)議直接位于IP(網(wǎng)際協(xié)議)協(xié)議的頂層。根據(jù)OSI(開(kāi)放系統(tǒng)互連)參考模型,UDP和TCP都屬于傳輸層協(xié)議。
UDP協(xié)議的主要作用是將網(wǎng)絡(luò)數(shù)據(jù)流量壓縮成數(shù)據(jù)報(bào)的形式。一個(gè)典型的數(shù)據(jù)報(bào)就是一個(gè)二進(jìn)制數(shù)據(jù)的傳輸單位。每一個(gè)數(shù)據(jù)報(bào)的前8個(gè)字節(jié)用來(lái)包含報(bào)頭信息,剩余字節(jié)則用來(lái)包含具體的傳輸數(shù)據(jù)。
TCP和UDP在android中的使用和在Java里是完全一樣的。
服務(wù)端:
package com.cheerchip.core;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import android.util.Log;
public class UDPServer implements Runnable {
private static final int PORT = 6000;
private byte[] msg = new byte[1024];
private boolean life = true;
public UDPServer() {
}
/**
* @return the life
*/
public boolean isLife() {
return life;
}
/**
* @param life
* the life to set
*/
public void setLife(boolean life) {
this.life = life;
}
@Override
public void run() {
DatagramSocket dSocket = null;
DatagramPacket dPacket = new DatagramPacket(msg, msg.length);
try {
dSocket = new DatagramSocket(PORT);
while (life) {
try {
dSocket.receive(dPacket);
Log.i("msg sever received", new String(dPacket.getData()));
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (SocketException e) {
e.printStackTrace();
}
}
}
客戶端:
package com.cheerchip.core;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UDPClient {
private static final int SERVER_PORT = 6000;
private DatagramSocket dSocket = null;
private String msg;
/**
* @param msg
*/
public UDPClient(String msg) {
super();
this.msg = msg;
}
/**
* 發(fā)送信息到服務(wù)器
*/
public String send() {
StringBuilder sb = new StringBuilder();
InetAddress local = null;
try {
local = InetAddress.getByName("localhost"); // 本機(jī)測(cè)試
sb.append("已找到服務(wù)器,連接中...").append("/n");
} catch (UnknownHostException e) {
sb.append("未找到服務(wù)器.").append("/n");
e.printStackTrace();
}
try {
dSocket = new DatagramSocket(); // 注意此處要先在配置文件里設(shè)置權(quán)限,否則會(huì)拋權(quán)限不足的異常
sb.append("正在連接服務(wù)器...").append("/n");
} catch (SocketException e) {
e.printStackTrace();
sb.append("服務(wù)器連接失敗.").append("/n");
}
int msg_len = msg == null ? 0 : msg.length();
DatagramPacket dPacket = new DatagramPacket(msg.getBytes(), msg_len,
local, SERVER_PORT);
try {
dSocket.send(dPacket);
sb.append("消息發(fā)送成功!").append("/n");
} catch (IOException e) {
e.printStackTrace();
sb.append("消息發(fā)送失敗.").append("/n");
}
dSocket.close();
return sb.toString();
}
}
主Activity:
public class MainAct extends Activity {
EditText msg_et = null;
Button send_bt = null;
TextView info_tv = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
msg_et = (EditText) findViewById(R.id.msg_et);
send_bt = (Button) findViewById(R.id.send_bt);
info_tv = (TextView) findViewById(R.id.info_tv);
// 開(kāi)啟服務(wù)器
ExecutorService exec = Executors.newCachedThreadPool();
UDPServer server = new UDPServer();
exec.execute(server);
// 發(fā)送消息
send_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
UDPClient client = new UDPClient(msg_et.getText().toString());
info_tv.setText(client.send());
}
});
}
}
注意在配置文件中要加上:
以獲取相應(yīng)的權(quán)限。
效果圖:
LogCat打印出來(lái)的服務(wù)器端信息:
- Android使用URLConnection提交請(qǐng)求的實(shí)現(xiàn)
- Android HttpURLConnection.getResponseCode()錯(cuò)誤解決方法
- Android 中HttpURLConnection與HttpClient使用的簡(jiǎn)單實(shí)例
- Android中HttpURLConnection與HttpClient的使用與封裝
- Android中使用HttpURLConnection實(shí)現(xiàn)GET POST JSON數(shù)據(jù)與下載圖片
- Android通過(guò)HttpURLConnection和HttpClient接口實(shí)現(xiàn)網(wǎng)絡(luò)編程
- Golang+Android基于HttpURLConnection實(shí)現(xiàn)的文件上傳功能示例
- Android開(kāi)發(fā)使用HttpURLConnection進(jìn)行網(wǎng)絡(luò)編程詳解【附源碼下載】
- android 網(wǎng)絡(luò)編程之網(wǎng)絡(luò)通信幾種方式實(shí)例分享
- Android開(kāi)發(fā)使用URLConnection進(jìn)行網(wǎng)絡(luò)編程詳解
相關(guān)文章
詳解flutter engine 那些沒(méi)被釋放的東西
這篇文章主要介紹了詳解flutter engine 那些沒(méi)被釋放的東西,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Android自定義view實(shí)現(xiàn)多色進(jìn)度條GradientProgressView的繪制
我們常使用shape實(shí)現(xiàn)漸變色,但是shape的極限卻只有三色,如果有超過(guò)三種顏色的View的要求,那么我們就不得不去自定義View來(lái)實(shí)現(xiàn)這個(gè)需求,所以下面我們就來(lái)看看如何自定義view實(shí)現(xiàn)多色進(jìn)度條的繪制吧2023-08-08Android自定義控件實(shí)現(xiàn)九宮格解鎖功能
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)九宮格解鎖功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05Android自定義View繪制的方法及過(guò)程(二)
這篇文章主要解析了Android自定義View繪制的方法及過(guò)程,介紹了onSizeChanged、onDraw、onMeasure順序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Android實(shí)現(xiàn)雙模(CDMA/GSM)手機(jī)短信監(jiān)聽(tīng)的方法
這篇文章主要介紹了Android實(shí)現(xiàn)雙模(CDMA/GSM)手機(jī)短信監(jiān)聽(tīng)的方法,涉及Android短信的原理與相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06手把手教你用ViewPager自定義實(shí)現(xiàn)Banner輪播
這篇文章主要手把手教你用ViewPager自定義實(shí)現(xiàn)Banner輪播,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09