Socket和Http是Android常用的兩種通信方式俩垃,但是兩者又是有所不同的励幼,使用場(chǎng)景有所不同,這篇文章就來總結(jié)總結(jié)這兩種方式口柳。
首先苹粟,Socket是什么呢?其實(shí)Socket就是一組接口而已跃闹,其實(shí)計(jì)算機(jī)網(wǎng)絡(luò)中通常會(huì)把通訊網(wǎng)絡(luò)分為5層模型:
Socket就是運(yùn)輸層和應(yīng)用層中間的抽象層嵌削,隱藏了TCP/IP協(xié)議簇(位于運(yùn)輸層)的具體實(shí)現(xiàn)毛好,所以位于應(yīng)用層的應(yīng)用想要和底層的運(yùn)輸層通信,直接調(diào)用Socket就行了苛秕。Socket的類型其實(shí)有兩種肌访,一種是TCP應(yīng)用服務(wù),一種是UDP應(yīng)用服務(wù)艇劫,有啥區(qū)別呢吼驶?
| TCP | UDP
----|-------|------
是否連接| 面向連接| 面向非連接
傳輸可靠性|可靠的| 不可靠的
應(yīng)用場(chǎng)合|傳輸大量的數(shù)據(jù)|少量數(shù)據(jù)
速度|慢|快
其實(shí)在Android中除了視頻音頻等對(duì)丟包率要求不高的情況,其它時(shí)候還是建議用TCP的港准。Socket不僅可以用于網(wǎng)絡(luò)通信,還可以用于應(yīng)用的跨進(jìn)程通信咧欣。Socket的使用方式也很簡(jiǎn)單浅缸。
public void startTcpSocketConnect(){
new Thread(new Runnable() {
@Override
public void run() {
try {
mSocket = new Socket(serverIp, serverPort);
in = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
mSocket.getOutputStream())), true);
while (true) {
if (mSocket.isConnected()) {
if (!mSocket.isInputShutdown()) {
if ((content = in.readLine()) != null) {
content += "\n";
if (mTcpSocketListener != null)
mTcpSocketListener.callBackContent(content);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
都是幾乎固定的寫法,沒什么稀奇的魄咕,網(wǎng)上一搜一堆代碼衩椒。
當(dāng)然UDP的話就是
socket = new DatagramSocket(1985);
....
DatagramPacket packet = new DatagramPacket(data, data.length ,serverAddress ,10025);
socket.send(packet);//把數(shù)據(jù)發(fā)送到服務(wù)端。
socket.receive(packet); //接收數(shù)據(jù)
再說Http哮兰,Http是建立在請(qǐng)求/響應(yīng)模型上的應(yīng)用層協(xié)議毛萌,客戶端首先建立一條與服務(wù)器的TCP連接并發(fā)送一個(gè)請(qǐng)求,然后服務(wù)器作出相應(yīng)的響應(yīng)喝滞。其中HTTP/1.0用的是短鏈接阁将,沒發(fā)送一次請(qǐng)求就會(huì)新建立一個(gè)連接,而每一個(gè)連接都要3次握手右遭,這是很耗費(fèi)資源的做盅,于是HTTP/1.1做出來改進(jìn),使用了長連接窘哈,只建立一個(gè)TCP連接重復(fù)使用其傳輸一些列的請(qǐng)求/響應(yīng)吹榴。這樣就節(jié)省了這種開銷了。
題外話滚婉,如果有一種協(xié)議即能像UDP那樣高效又能像TCP那樣的可靠就好了图筹,哈哈,不過聽說有人已經(jīng)在研究UDP和TCP混合的HTTP了让腹,不知道是不是真的远剩。
既然Http是基于TCP之上的,那么可不可以用Socket來實(shí)現(xiàn)下Http呢骇窍?答案當(dāng)然是可以的民宿。
static void get(String url) throws IOException {
String host = new URL("http://" + url).getHost();
String path = url.substring(host.length());
InetSocketAddress address = new InetSocketAddress(host, 80);
Socket socket = new Socket();
socket.connect(address);
OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());
BufferedWriter bufferedWriter = new BufferedWriter(streamWriter);
bufferedWriter.write("GET " + path + " HTTP/1.1\r\n");
bufferedWriter.write("Host: " + host + "\r\n");
bufferedWriter.write("Content-Type: application/x-www-form-urlencoded\r\n");
bufferedWriter.write("\r\n");
bufferedWriter.flush();
BufferedInputStream inputStream = new BufferedInputStream(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String line;
while ((line = bufferedReader.readLine()) != null) {
Log.d("1234", line);
}
bufferedReader.close();
bufferedWriter.close();
socket.close();
}```
這里只是實(shí)現(xiàn)了get方法,其實(shí)post方法也是一樣的原理的請(qǐng)求頭最好加上“Content-Length”和“Content-Type”像鸡,另外需要注意的是傳輸?shù)臄?shù)據(jù)最好編碼一下活鹰,以免出現(xiàn)亂碼或編碼錯(cuò)誤哈恰。