TCP和UDP在網絡傳輸中很是重要,在Android開發中一樣重要。android
首先咱們來看一下什麼是TCP和UDP。算法
什麼是TCP?安全
TCP:Transmission Control Protocol 傳輸控制協議TCP是一種面向鏈接(鏈接導向)的、可靠的、基於字節流的運輸層(Transport layer)通訊協議,由IETF的RFC 793說明(specified)。在簡化的計算機網絡OSI模型中,它完成第四層傳輸層所指定的功能。應用層向TCP層發送用於網間傳輸的、用8位字節表示的數據流,而後TCP把數據流分割成適當長度的報文段(一般受該計算機鏈接的網絡的數據鏈路層的最大傳送單元(MTU)的限制)。以後TCP把結果包傳給IP層,由它來經過網絡將包傳送給接收端實體的TCP層。TCP爲了保證不發生丟包,就給每一個字節一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。而後接收端實體對已成功收到的字節發回一個相應的確認(ACK);若是發送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的數據(假設丟失了)將會被重傳。TCP用一個校驗和函數來檢驗數據是否有錯誤;在發送和接收時都要計算校驗和。服務器
首先,TCP創建鏈接以後,通訊雙方都同時能夠進行數據的傳輸,其次,他是全雙工的;在保證可靠性上,採用超時重傳和捎帶確認機制。網絡
在流量控制上,採用滑動窗口協議[1],協議中規定,對於窗口內未經確認的分組須要重傳。app
在擁塞控制上,採用慢啓動算法。socket
什麼是UDP?函數
UDP 是User Datagram Protocol的簡稱, 中文名是用戶數據包協議,是 OSI 參考模型中一種無鏈接的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務。它是IETF RFC 768是UDP的正式規範。在網絡中它與TCP協議同樣用於處理數據包。在OSI模型中,在第四層——傳輸層,處於IP協議的上一層。UDP有不提供數據報分組、組裝和不能對數據包的排序的缺點,也就是說,當報文發送以後,是沒法得知其是否安全完整到達的。 UDP用來支持那些須要在計算機之間傳輸數據的網絡應用。包括網絡視頻會議系統在內的衆多的客戶/服務器模式的網絡應用都須要使用UDP協議。UDP協議從問世至今已經被使用了不少年,雖然其最初的光彩已經被一些相似協議所掩蓋,可是即便是在今天,UDP仍然不失爲一項很是實用和可行的網絡傳輸層協議。spa
與所熟知的TCP(傳輸控制協議)協議同樣,UDP協議直接位於IP(網際協議)協議的頂層。根據OSI(開放系統互連)參考模型,UDP和TCP都屬於傳輸層協議。計算機網絡
UDP協議的主要做用是將網絡數據流量壓縮成數據報的形式。一個典型的數據報就是一個二進制數據的傳輸單位。每個數據報的前8個字節用來包含報頭信息,剩餘字節則用來包含具體的傳輸數據。
TCP和UDP在android中的使用和在Java裏是徹底同樣的。
首先咱們看看TCP鏈接,下圖爲TCP鏈接的一個示意圖:
是否是很好理解,這裏就很少說了,直接看代碼吧!實踐出真知。
TCP服務器端代碼:
try {
Boolean endFlag = false;
ServerSocket ss = new ServerSocket(12345);
while (!endFlag) {
// 等待客戶端鏈接
Socket s = ss.accept();
BufferedReader input = new BufferedReader(newInputStreamReader(s.getInputStream()));
//注意第二個參數據爲true將會自動flush,不然須要須要手動操做output.flush()
PrintWriter output = newPrintWriter(s.getOutputStream(),true);
String message = input.readLine();
Log.d("Tcp Demo", "message from Client:"+message);
output.println("message received!");
//output.flush();
if("shutDown".equals(message)){
endFlag=true;
}
s.close();
}
ss.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
TCP客戶端代碼:
try {
Socket s = new Socket("localhost", 12345);
// outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
// 注意第二個參數據爲true將會自動flush,不然須要須要手動操做out.flush()
PrintWriter output = new PrintWriter(out, true);
output.println("Hello IdeasAndroid!");
BufferedReader input = new BufferedReader(newInputStreamReader(s
.getInputStream()));
// read line(s)
String message = input.readLine();
Log.d("Tcp Demo", "message From Server:" + message);
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
下面咱們看看UDP:
UDP服務器端代碼:
// UDP服務器監聽的端口
Integer port = 12345;
// 接收的字節大小,客戶端發送的數據不能超過這個大小
byte[] message = new byte[1024];
try {
// 創建Socket鏈接
DatagramSocket datagramSocket = new DatagramSocket(port);
DatagramPacket datagramPacket = new DatagramPacket(message,
message.length);
try {
while (true) {
// 準備接收數據
datagramSocket.receive(datagramPacket);
Log.d("UDP Demo", datagramPacket.getAddress()
.getHostAddress().toString()
+ ":" + new String(datagramPacket.getData()));
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (SocketException e) {
e.printStackTrace();
}
UDP客戶端代碼:
public static void send(String message) {
message = (message == null ? "Hello IdeasAndroid!" : message);
int server_port = 12345;
DatagramSocket s = null;
try {
s = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
InetAddress local = null;
try {
// 換成服務器端IP
local = InetAddress.getByName("localhost");
} catch (UnknownHostException e) {
e.printStackTrace();
}
int msg_length = message.length();
byte[] messagemessageByte = message.getBytes();
DatagramPacket p = new DatagramPacket(messageByte, msg_length, local,
server_port);
try {
s.send(p);
} catch (IOException e) {
e.printStackTrace();
}
}
代碼中須要注意的地方已作了註釋,但願本文對您有所幫助!