亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

網(wǎng)絡(luò)編程 -- 從 Socket 編程 到 OkHttp 框架

BWrong / 2079人閱讀

摘要:如端口號(hào)分為標(biāo)準(zhǔn)既定的端口號(hào)其中知名端口號(hào)由組成。協(xié)議中,使用數(shù)據(jù)報(bào)為傳輸單位。用于直播等網(wǎng)速要求較高的應(yīng)用端到端的通信類本機(jī)地址隨機(jī)指定發(fā)送與接收數(shù)據(jù)報(bào)為和等網(wǎng)絡(luò)層以上的包的單位。

前言

最近在做一個(gè)項(xiàng)目的時(shí)候,因?yàn)轫?xiàng)目要求跨域連接。所以,使用了Okhttp框架。其內(nèi)部原理是基于 socket 網(wǎng)絡(luò)編程的。因?yàn)樽约涸谶@方面比較薄弱,所以寫(xiě)這一篇文章進(jìn)行相關(guān)的總結(jié)。

基礎(chǔ)知識(shí)(參考 圖解TCP/IP 與 深入理解計(jì)算機(jī)系統(tǒng))

1、TCP/IP 參考模型
這位大佬寫(xiě)的很詳細(xì)---點(diǎn)擊即看

2、socket 套接字
每個(gè)套接字都是連接的一個(gè)端點(diǎn),有相應(yīng)的套接字地址。由一個(gè)IP地址與16位的整數(shù)端口組成.一個(gè)連接由兩端的套接字地址唯一確定。叫套接字對(duì)。
如:(cliaddr:cliport, servaddr:servport)
端口號(hào)分為:
標(biāo)準(zhǔn)既定的端口號(hào): 0~49151. 其中知名端口號(hào)由 0~1023 ** 組成。FTP 一般使用 21號(hào)端口號(hào),HTTP 通信一般使用 80 號(hào)端口號(hào)。
動(dòng)態(tài)分配的端口號(hào): 49152~65535. 操作系統(tǒng)為之分配不同的端口號(hào)。然后應(yīng)用程序使用時(shí),由操作系統(tǒng)將連接建立。

3、java 中的網(wǎng)絡(luò)編程類

InetAddress:用于標(biāo)識(shí)網(wǎng)絡(luò)上的硬件資源,主要是IP地址
URL:統(tǒng)一資源定位符,通過(guò)URL可以直接讀取或?qū)懭刖W(wǎng)絡(luò)上的數(shù)據(jù)
Sockets:使用TCP協(xié)議實(shí)現(xiàn)的網(wǎng)絡(luò)通信Socket相關(guān)的類
Datagram:使用UDP協(xié)議,將數(shù)據(jù)保存在用戶數(shù)據(jù)報(bào)中,通過(guò)網(wǎng)絡(luò)進(jìn)行通信。UDP協(xié)議中,使用 數(shù)據(jù)報(bào) 為傳輸單位。
java 網(wǎng)絡(luò)編程類介紹 1. InetAddress

InetAddress類用于標(biāo)識(shí)網(wǎng)絡(luò)上的硬件資源,標(biāo)識(shí)互聯(lián)網(wǎng)協(xié)議(IP)地址。

//獲取本機(jī)的InetAddress實(shí)例
InetAddress address =InetAddress.getLocalHost();
//獲取計(jì)算機(jī)名
address.getHostName();
//獲取IP地址
address.getHostAddress();
//獲取字節(jié)數(shù)組形式的IP地址,以點(diǎn)分隔的四部分
byte[] bytes = address.getAddress();

//獲取其他主機(jī)的InetAddress實(shí)例
InetAddress address2 =InetAddress.getByName("其他主機(jī)名");
InetAddress address3 =InetAddress.getByName("IP地址");
2. URL

URL(Uniform Resource Locator)統(tǒng)一資源定位符,表示Internet上某一資源的地址,協(xié)議名:資源名稱

基礎(chǔ)使用

  //創(chuàng)建一個(gè)URL的實(shí)例
  URL myBlog =new URL("https://3dot141.cn");
  URL url =new URL(myBlog,"/blogs/33521.html?username=3dot141#test");//?表示參數(shù),#表示錨點(diǎn)
  url.getProtocol();//獲取協(xié)議
  url.getHost();//獲取主機(jī)
  url.getPort();//如果沒(méi)有指定端口號(hào),根據(jù)協(xié)議不同使用默認(rèn)端口。此時(shí)getPort()方法的返回值為 -1
  url.getPath();//獲取文件路徑
  url.getFile();//文件名,包括文件路徑+參數(shù)
  url.getRef();//相對(duì)路徑,就是錨點(diǎn),即#號(hào)后面的內(nèi)容
  url.getQuery();//查詢字符串,即參數(shù)

讀取網(wǎng)頁(yè)內(nèi)容

  //使用URL讀取網(wǎng)頁(yè)內(nèi)容
  //創(chuàng)建一個(gè)URL實(shí)例
  URL url =new URL("http://www.baidu.com");
  InputStream is = url.openStream();//通過(guò)openStream方法獲取資源的字節(jié)輸入流
  InputStreamReader isr =newInputStreamReader(is,"UTF-8");//將字節(jié)輸入流轉(zhuǎn)換為字符輸入流,如果不指定編碼,中文可能會(huì)出現(xiàn)亂碼
  BufferedReader br =newBufferedReader(isr);//為字符輸入流添加緩沖,提高讀取效率
  String data = br.readLine();//讀取數(shù)據(jù)
  while(data!=null){
  System.out.println(data);//輸出數(shù)據(jù)
  data = br.readerLine();
  }
  br.close();
  isr.colose();
  is.close();
3. Socket

首先介紹下關(guān)于 linux 下的套接字連接原理,幫助理解

下面介紹java 下 Socket的使用

1.Socket 的構(gòu)造方法
(1)Socket()

(2)Socket(InetAddress address, int port)throws UnknownHostException,IOException

// 設(shè)定遠(yuǎn)程服務(wù)器地址與客戶端地址
(3)Socket(InetAddress address, int port, InetAddress localAddr, int localPort)throws IOException

(4)Socket(String host, int port) throws UnknownHostException,IOException

// 設(shè)定遠(yuǎn)程服務(wù)器地址與客戶端地址
(5)Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException
2.獲取Socket信息
1. getInetAddress():獲得遠(yuǎn)程服務(wù)器的IP地址。

2. getPort():獲得遠(yuǎn)程服務(wù)器的端口。

3. getLocalAddress():獲得客戶本地的IP地址。

4. getLocalPort():獲得客戶本地的端口。

5. getInputStream():獲得輸入流。如果Socket還沒(méi)有連接,或者已經(jīng)關(guān)閉,或者已經(jīng)通過(guò)shutdownInput()方法關(guān)閉輸入流,那么此方法會(huì)拋出IOException。

6. getOutputStream():獲得輸出流。如果Socket還沒(méi)有連接,或者已經(jīng)關(guān)閉,或者已經(jīng)通過(guò)shutdownOutput()方法關(guān)閉輸出流,那么此方法會(huì)拋出IOException。
3.Socket 狀態(tài)

關(guān)閉狀態(tài)

1. close()

// 狀態(tài)測(cè)試方法
1. isClosed()
2. IsConnected()
3. isBound()

半關(guān)閉狀態(tài)

1. shutdownInput()
2. shutdownOutput()

// 狀態(tài)測(cè)試方法
1. isInputShutDown()
2. isOutputShutdown()
4.Socket 使用實(shí)例

以上就是 Socket 類的基本方法。 下面讓我們進(jìn)入實(shí)戰(zhàn),來(lái)看一下,Socket 類如何使用

服務(wù)器端

/**
 * 基于TCP協(xié)議的Socket通信,實(shí)現(xiàn)用戶登錄,服務(wù)端
*/
//1、創(chuàng)建一個(gè)服務(wù)器端Socket,即ServerSocket,指定綁定的端口,并監(jiān)聽(tīng)此端口
ServerSocket serverSocket =newServerSocket(33521);//1024-65535的某個(gè)端口
//2、調(diào)用accept()方法開(kāi)始監(jiān)聽(tīng),等待客戶端的連接
Socket socket = serverSocket.accept();
//3、獲取輸入流,并讀取客戶端信息
InputStream is = socket.getInputStream();
InputStreamReader isr =newInputStreamReader(is);
BufferedReader br =newBufferedReader(isr);
String info =null;
while((info=br.readLine())!=null){
System.out.println("我是服務(wù)器,客戶端說(shuō):"+info);
}
socket.shutdownInput();//關(guān)閉輸入流

//4、獲取輸出流,響應(yīng)客戶端的請(qǐng)求
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.write("歡迎您!");
pw.flush();


//5、關(guān)閉資源
pw.close();
os.close();
br.close();
isr.close();
is.close();
socket.close();
serverSocket.close();

客戶端

//客戶端
//1、創(chuàng)建客戶端Socket,指定服務(wù)器地址和端口
Socket socket =newSocket("localhost",33521);
//2、獲取輸出流,向服務(wù)器端發(fā)送信息
OutputStream os = socket.getOutputStream();//字節(jié)輸出流
PrintWriter pw =newPrintWriter(os);//將輸出流包裝成打印流
pw.write("用戶名:3dot141;密碼:hahah");
pw.flush();
socket.shutdownOutput();
//3、獲取輸入流,并讀取服務(wù)器端的響應(yīng)信息
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while((info=br.readLine())!null){
 System.out.println("我是客戶端,服務(wù)器說(shuō):"+info);
}

//4、關(guān)閉資源
br.close();
is.close();
pw.close();
os.close();
socket.close();

結(jié)果

我是服務(wù)器,客戶端說(shuō):用戶名:3dot141;密碼:hahah
我是客戶端,服務(wù)器說(shuō):歡迎您! 

多線程中的運(yùn)用

服務(wù)器端創(chuàng)建ServerSocket,使用while(true)循環(huán)調(diào)用accept()等待客戶端連接

客戶端創(chuàng)建一個(gè)socket并請(qǐng)求和服務(wù)器端連接

服務(wù)器端接受請(qǐng)求,創(chuàng)建socket與該客戶建立專線連接

建立連接的兩個(gè)socket在一個(gè)多帶帶的線程上對(duì)話

服務(wù)器端繼續(xù)等待新的連接

public class ServerThread implements runnable{
//服務(wù)器線程處理
//和本線程相關(guān)的socket
Socket socket =null;
//
public ServerThread(Socket socket){
this.socket = socket;
}

publicvoid run(){
//服務(wù)器處理代碼
}
}

//服務(wù)器代碼
ServerSocket serverSocket =newServerSocket(33521);
Socket socket =null;
int count =0;//記錄客戶端的數(shù)量
while(true){
socket = serverScoket.accept();
ServerThread serverThread =new ServerThread(socket);
 serverThread.start();
 count++;
System.out.println("客戶端連接的數(shù)量:"+count);
}
4. UDP 編程 1. 簡(jiǎn)單介紹

UDP 是面向無(wú)連接的協(xié)議,反應(yīng)迅速,適用于適時(shí)場(chǎng)景,但是丟包后不能發(fā)現(xiàn)。
用于 直播等網(wǎng)速要求較高的應(yīng)用

DatagramSocket 端到端的通信類.

//本機(jī)地址
// 隨機(jī)
DatagramSocket()
// 指定
DatagramSocket(int port, InetAddress)


// 發(fā)送與接收
send(DatagramPacket) 
receive(DatagramPacket)

DatagramPacket 數(shù)據(jù)報(bào), 為 IP 和 UDP 等網(wǎng)絡(luò)層以上的包的單位 。雖然這些都是包,但不同的層擁有不同的稱呼。數(shù)據(jù)鏈路層中 叫 , TCP 則表示 為 .
方法

// 構(gòu)造方法
// 接收時(shí)
DatagramPacket(byte[] buf, int length);
// 發(fā)送時(shí)
DatagramPacket(byte[] buf, int length, InetAddress iAdrr, int Port);

// 使用方法
// 用于服務(wù)器獲得 客戶端地址
getAddress()
// 用于服務(wù)器獲得 客戶端接口
getPort()
2. 基本使用

服務(wù)器端

//服務(wù)器端,實(shí)現(xiàn)基于UDP的用戶登錄
//1、創(chuàng)建服務(wù)器端DatagramSocket,指定端口
DatagramSocket socket =new datagramSocket(33521);
//2、創(chuàng)建數(shù)據(jù)報(bào),用于接受客戶端發(fā)送的數(shù)據(jù)
byte[] data =newbyte[1024];//
DatagramPacket packet =newDatagramPacket(data,data.length);
//3、接受客戶端發(fā)送的數(shù)據(jù)
socket.receive(packet);//此方法在接受數(shù)據(jù)報(bào)之前會(huì)一致阻塞
//4、讀取數(shù)據(jù)
String info =newString(data,o,data.length);
System.out.println("我是服務(wù)器,客戶端告訴我"+info);


//=========================================================
//向客戶端響應(yīng)數(shù)據(jù)
//1、定義客戶端的地址、端口號(hào)、數(shù)據(jù)
// 這里也可以自己設(shè)置
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "歡迎您!".geyBytes();
//2、創(chuàng)建數(shù)據(jù)報(bào),包含響應(yīng)的數(shù)據(jù)信息
DatagramPacket packet2 = new DatagramPacket(data2,data2.length,address,port);
//3、響應(yīng)客戶端
socket.send(packet2);
//4、關(guān)閉資源
socket.close();

客戶端

//客戶端
//1、定義服務(wù)器的地址、端口號(hào)、數(shù)據(jù)
InetAddress address =InetAddress.getByName("localhost");
int port =33521;
byte[] data ="用戶名:3dot141;密碼:hahah".getBytes();
//2、創(chuàng)建數(shù)據(jù)報(bào),包含發(fā)送的數(shù)據(jù)信息
DatagramPacket packet = newDatagramPacket(data,data,length,address,port);
//3、創(chuàng)建DatagramSocket對(duì)象
DatagramSocket socket =newDatagramSocket();
//4、向服務(wù)器發(fā)送數(shù)據(jù)
socket.send(packet);


//接受服務(wù)器端響應(yīng)數(shù)據(jù)
//======================================
//1、創(chuàng)建數(shù)據(jù)報(bào),用于接受服務(wù)器端響應(yīng)數(shù)據(jù)
byte[] data2 = new byte[1024];
DatagramPacket packet2 = new DatagramPacket(data2,data2.length);
//2、接受服務(wù)器響應(yīng)的數(shù)據(jù)
socket.receive(packet2);
String raply = new String(data2,0,packet2.getLenth());
System.out.println("我是客戶端,服務(wù)器說(shuō):"+reply);
//4、關(guān)閉資源
socket.close();
OkHttp 框架

在項(xiàng)目中,我對(duì) OkHttp 進(jìn)行了簡(jiǎn)單的封裝,基本滿足我在項(xiàng)目中的需要。
下面貼上我的 工具類

public class OkhttpUtil {
    public static final MediaType JSON = MediaType.parse("application/json;charset=UTF-8");

    public static String doGet(String url) throws IOException {
        OkHttpClient client = new OkHttpClient();
        Request get = new Request.Builder().url(url).build();
        Response response = client.newCall(get).execute();
        return response.body().string();
    }

    public static String doGet(String url, Map map) throws IOException {
        OkHttpClient client = new OkHttpClient();
        String newUrl = url;
        if (map != null) {
            int loop = 0;
            for (String key : map.keySet()) {
                if (loop == 0) {
                    newUrl = newUrl + "?" + key + "=" + map.get(key);
                } else {
                    newUrl = newUrl + "&" + key + "=" + map.get(key);
                }
                loop = 1;
            }
        }
        Request get = new Request.Builder().url(newUrl).build();
        Response response = client.newCall(get).execute();

        return response.body().string();
    }

    public static String doPost(String url, String requestBody) throws IOException {
        OkHttpClient client = new OkHttpClient();
        Request post = new Request.Builder().url(url).post(RequestBody.create(JSON, requestBody)).build();
        Response response = client.newCall(post).execute();
        if (!response.isSuccessful()) {
            throw new IOException("沒(méi)能得到數(shù)據(jù)" + response);
        }
        return response.body().string();

    }
}

如果有對(duì) okhttp 框架感興趣的,可以參閱下面的網(wǎng)址。我就不獻(xiàn)丑了。
okhttp 源碼解析
okhttp 使用教程

結(jié)語(yǔ)

路漫漫其修遠(yuǎn)兮,吾將上下而求索。
在程序員的道路上,我還只是一個(gè)剛上路的小學(xué)生,懷著對(duì)代碼世界的向往,砥礪前行。

stay hungry, stay foolish
與諸君共勉。
您的每一次點(diǎn)贊,關(guān)注都是對(duì)我的一種激勵(lì)。

我的個(gè)人博客 -- killCode
謝謝。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/70466.html

相關(guān)文章

  • Android網(wǎng)絡(luò)編程8之源碼解析OkHttp中篇[復(fù)用連接池]

    摘要:構(gòu)造函數(shù)默認(rèn)空閑的最大連接數(shù)為個(gè),的時(shí)間為秒通過(guò)構(gòu)造函數(shù)可以看出默認(rèn)的空閑的最大連接數(shù)為個(gè),的時(shí)間為秒。實(shí)例化實(shí)例化是在實(shí)例化時(shí)進(jìn)行的在的構(gòu)造函數(shù)中調(diào)用了省略省略緩存操作提供對(duì)進(jìn)行操作的方法分別為和幾個(gè)操作。 1.引子 在了解OkHttp的復(fù)用連接池之前,我們首先要了解幾個(gè)概念。 TCP三次握手 通常我們進(jìn)行HTTP連接網(wǎng)絡(luò)的時(shí)候我們會(huì)進(jìn)行TCP的三次握手,然后傳輸數(shù)據(jù),然后再釋放連接...

    fasss 評(píng)論0 收藏0
  • 網(wǎng)絡(luò)編程 - 收藏集 - 掘金

    摘要:個(gè)高級(jí)多線程面試題及回答后端掘金在任何面試當(dāng)中多線程和并發(fā)方面的問(wèn)題都是必不可少的一部分。目前在生產(chǎn)環(huán)基于的技術(shù)問(wèn)答網(wǎng)站系統(tǒng)實(shí)現(xiàn)后端掘金這一篇博客將詳細(xì)介紹一個(gè)基于的問(wèn)答網(wǎng)站的實(shí)現(xiàn),有詳細(xì)的代碼。 15 個(gè)高級(jí) Java 多線程面試題及回答 - 后端 - 掘金在任何Java面試當(dāng)中多線程和并發(fā)方面的問(wèn)題都是必不可少的一部分。如果你想獲得任何股票投資銀行的前臺(tái)資訊職位,那么你應(yīng)該準(zhǔn)備很多...

    justCoding 評(píng)論0 收藏0
  • 網(wǎng)絡(luò)編程 - 收藏集 - 掘金

    摘要:個(gè)高級(jí)多線程面試題及回答后端掘金在任何面試當(dāng)中多線程和并發(fā)方面的問(wèn)題都是必不可少的一部分。目前在生產(chǎn)環(huán)基于的技術(shù)問(wèn)答網(wǎng)站系統(tǒng)實(shí)現(xiàn)后端掘金這一篇博客將詳細(xì)介紹一個(gè)基于的問(wèn)答網(wǎng)站的實(shí)現(xiàn),有詳細(xì)的代碼。 15 個(gè)高級(jí) Java 多線程面試題及回答 - 后端 - 掘金在任何Java面試當(dāng)中多線程和并發(fā)方面的問(wèn)題都是必不可少的一部分。如果你想獲得任何股票投資銀行的前臺(tái)資訊職位,那么你應(yīng)該準(zhǔn)備很多...

    selfimpr 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<