TCP、UDP及服務屏蔽實現(xiàn)方式

目錄

1. TCP注暗、UDP

2. Java Tcp

3. Java Upd

4. 降級的幾種方式

5. 降級的實現(xiàn)方式之一

6. 故障中降級的意義

7. 總結(jié)及展望


1. TCP炼幔、UDP

  • TCP/IP協(xié)議棧主要分為四層:應用層、傳輸層扫沼、網(wǎng)絡層、數(shù)據(jù)鏈路層,每層都有相應的協(xié)議庄吼,所謂的協(xié)議就是雙方進行數(shù)據(jù)傳輸?shù)囊环N格式。

  • 應用層:用戶進程

  • 傳輸層:TCP严就、UDP

  • 網(wǎng)絡層:ICMP总寻、IP、IGMP

  • 鏈路層:ARP梢为、硬件接口渐行、RARP

  • 網(wǎng)絡中,一幀以太網(wǎng)數(shù)據(jù)包的格式如下:

    | Ethernet頭 | IP頭 | TCP/UDP頭 | 數(shù)據(jù) |


    image

    在Linux 操作系統(tǒng)中铸董,當我們想發(fā)送數(shù)據(jù)的時候祟印,我們只需要在上層準備好數(shù)據(jù),然后提交給內(nèi)核協(xié)議棧 , 內(nèi)核協(xié)議棧自動添加相應的協(xié)議頭粟害。

    1.1. TCP

  • TCP協(xié)議是面向連接蕴忆、保證高可靠性(數(shù)據(jù)無丟失、數(shù)據(jù)無失序悲幅、數(shù)據(jù)無錯誤套鹅、數(shù)據(jù)無重復到達)傳輸層協(xié)議。

  • TCP頭分析

    image


(1)端口號[16bit]

網(wǎng)絡實現(xiàn)的是不同主機的進程間通信汰具。在一個操作系統(tǒng)中卓鹿,有很多進程,當數(shù)據(jù)到來時要提交給哪個進程進行處理呢?這就需要用到端口號留荔。在TCP頭中吟孙,有源端口號(Source Port)和目標端口號(Destination Port)。源端口號標識了發(fā)送主機的進程,目標端口號標識接受方主機的進程。

(2)序號[32bit]

序號分為發(fā)送序號(Sequence Number)和確認序號(Acknowledgment Number)杰妓。

發(fā)送序號:用來標識從 TCP源端向 TCP目的端發(fā)送的數(shù)據(jù)字節(jié)流藻治,它表示在這個報文段中的第一個數(shù)據(jù)字節(jié)的順序號。如果將字節(jié)流看作在兩個應用程序間的單向流動稚失,則 TCP用順序號對每個字節(jié)進行計數(shù)栋艳。序號是 32bit的無符號數(shù),序號到達 2  32- 1后又從 0開始句各。當建立一個新的連接時吸占, SYN標志變 1,順序號字段包含由這個主機選擇的該連接的初始順序號 ISN( Initial Sequence Number)凿宾。

確認序號:包含發(fā)送確認的一端所期望收到的下一個順序號矾屯。因此,確認序號應當是上次已成功收到數(shù)據(jù)字節(jié)順序號加 1初厚。只有 ACK標志為 1時確認序號字段才有效件蚕。 TCP為應用層提供全雙工服務,這意味數(shù)據(jù)能在兩個方向上獨立地進行傳輸产禾。因此排作,連接的每一端必須保持每個方向上的傳輸數(shù)據(jù)順序號。

(3)偏移[4bit]

這里的偏移實際指的是TCP首部的長度亚情,它用來表明TCP首部中32 bit字的數(shù)目妄痪,通過它可以知道一個TCP包它的用戶數(shù)據(jù)是從哪里開始的。這個字段占4bit,如4bit的值是0101,則說明TCP首部長度是5 * 4 = 20字節(jié)楞件。 所以TCP的首部長度最大為15 * 4 = 60字節(jié)衫生。然而沒有可選字段,正常長度為20字節(jié)土浸。

(4)Reserved [6bit]

目前沒有使用罪针,它的值都為0

(5)標志[6bit]

在TCP首部中有6個標志比特。他們中的多個可同時被置為1 黄伊。

URG         緊急指針(urgent pointer)有效
ACK          確認序號有效
PSH          指示接收方應該盡快將這個報文段交給應用層而不用等待緩沖區(qū)裝滿

RST           一般表示斷開一個連接
例如:一個TCP的客戶端向一個沒有監(jiān)聽的端口的服務器端發(fā)起連接,wirshark抓包如下
image

可以看到host:192.168.63.134向host:192.168.63.132發(fā)起連接請求泪酱,但是host:192.168.63.132并沒有處于監(jiān)聽對應端口的服務器端,這時
host : 192.168.63.132發(fā)一個RST置位的TCP包斷開連接。

SYN          同步序號用來發(fā)起一個連接
FIN            發(fā)送端完成發(fā)送任務(即斷開連接)

(6)窗口大小(window)[16bit]

窗口的大小毅舆,表示源方法最多能接受的字節(jié)數(shù)西篓。。

(7)校驗和[16bit]

校驗和覆蓋了整個的TCP報文段:TCP首部和TCP數(shù)據(jù)憋活。這是一個強制性的字段岂津,一定是由發(fā)端計算和存儲,并由收端進行驗證悦即。

(8)緊急指針[16bit]

只有當URG標志置為1時緊急指針才有效吮成。緊急指針是一個正的偏移量橱乱,和序號字段中的值相加表示緊急數(shù)據(jù)最后一個字節(jié)的序號。TCP的緊急方式是發(fā)送端向另一端發(fā)送緊急數(shù)據(jù)的一種方式粱甫。

(9)TCP選項

是可選的,在后面抓包的時候泳叠,我們在看看它

  • ==TCP 三次握手建立連接==

a.請求端(通常稱為客戶)發(fā)送一個SYN段指明客戶打算連接的服務器的端口,以及初始序號(ISN,在這個例子中為1415531521)茶宵。這個SYN段為報文段1危纫。

b.服務器發(fā)回包含服務器的初始序號的SYN報文段(報文段2)作為應答。同時乌庶,將確認序號設(shè)置為客戶的ISN加1以對客戶的SYN報文段進行確認种蝶。一個SYN將占用一個序號

c.客戶必須將確認序號設(shè)置為服務器的ISN加1以對服務器的SYN報文段進行確認(報文段3)

這三個報文段完成連接的建立。這個過程也稱為三次握手(three-way handshake)

image
  • ==TCP 四次揮手斷開連接==

a.現(xiàn)在的網(wǎng)絡通信都是基于socket實現(xiàn)的瞒大,當客戶端將自己的socket進行關(guān)閉時螃征,內(nèi)核協(xié)議棧會向服務器自動發(fā)送一個FIN置位的包,請求斷開連接透敌。我們稱首先發(fā)起斷開請求的一方稱為主動斷開方盯滚。

b.服務器端收到請客端的FIN斷開請求后,內(nèi)核協(xié)議棧會立即發(fā)送一個ACK包作為應答酗电,表示已經(jīng)收到客戶端的請求

c.服務器運行一段時間后魄藕,關(guān)閉了自己的socket。這個時候內(nèi)核協(xié)議棧會向客戶端發(fā)送一個FIN置位的包撵术,請求斷開連接

d.客戶端收到服務端發(fā)來的FIN斷開請求后泼疑,會發(fā)送一個ACK做出應答,表示已經(jīng)收到服務端的請求

image
  • TCP可靠性的保證

TCP采用一種名為“帶重傳功能的肯定確認(positive acknowledge with retransmission)”的技術(shù)作為提供可靠數(shù)據(jù)傳輸服務的基礎(chǔ)荷荤。這項技術(shù)要求接收方收到數(shù)據(jù)之后向源站回送確認信息ACK。發(fā)送方對發(fā)出的每個分組都保存一份記錄移稳,在發(fā)送下一個分組之前等待確認信息蕴纳。發(fā)送方還在送出分組的同時啟動一個定時器,并在定時器的定時期滿而確認信息還沒有到達的情況下个粱,重發(fā)剛才發(fā)出的分組古毛。圖3-5表示帶重傳功能的肯定確認協(xié)議傳輸數(shù)據(jù)的情況,圖3-6表示分組丟失引起超時和重傳都许。為了避免由于網(wǎng)絡延遲引起遲到的確認和重復的確認稻薇,協(xié)議規(guī)定在確認信息中稍帶一個分組的序號,使接收方能正確將分組與確認關(guān)聯(lián)起來胶征。
從圖 3-5可以看出塞椎,雖然網(wǎng)絡具有同時進行雙向通信的能力,但由于在接到前一個分組的確認信息之前必須推遲下一個分組的發(fā)送睛低,簡單的肯定確認協(xié)議浪費了大量寶貴的網(wǎng)絡帶寬案狠。為此服傍, TCP使用滑動窗口的機制來提高網(wǎng)絡吞吐量,同時解決端到端的流量控制骂铁。

image
  • 滑動窗口技術(shù)
滑動窗口技術(shù)是簡單的帶重傳的肯定確認機制的一個更復雜的變形吹零,它允許發(fā)送方在等待一個確認信息之前可以發(fā)送多個分組。如圖 3-7所示拉庵,發(fā)送方要發(fā)送一個分組序列灿椅,滑動窗口協(xié)議在分組序列中放置一個固定長度的窗口,然后將窗口內(nèi)的所有分組都發(fā)送出去钞支;當發(fā)送方收到對窗口內(nèi)第一個分組的確認信息時茫蛹,它可以向后滑動并發(fā)送下一個分組;隨著確認的不斷到達伸辟,窗口也在不斷的向后滑動麻惶。

image

### 1.2. UDP

  • UDP協(xié)議
    UDP協(xié)議也是傳輸層協(xié)議,它是無連接信夫,不保證可靠的傳輸層協(xié)議窃蹋。它的協(xié)議頭比較簡單
image

2. TCP java實現(xiàn)

image

image
  • TCPServer

import java.io.*;
import java.net.*;
class TCPServer{
    public static void main(String[] args)throws IOException{
        ServerSocket listen = new ServerSocket(5050);
        
        Socket server  = listen.accept();
        InputStream in = server.getInputStream();
        OutputStream out = server.getOutputStream();
        char c = (char)in.read();
        System.out.println("收到:" + c);
        out.write('s');
        
        out.close();
        in.close();
        server.close();
        listen.close();
    }
}

  • TCPClient

import java.io.*;
import java.net.*;
class TCPClient{
    public static void main(String[] args)throws IOException{
        Socket client = new Socket("127.0.0.1" , 5050);
        InputStream in = client.getInputStream();
        OutputStream out = client.getOutputStream();
        
        out.write('c');
        char c = (char)in.read();
        System.out.println("收到:" + c);
        out.close();
        in.close();
        client.close();
    }
}

3. UDP java實現(xiàn)

  • UDP和TCP有兩個典型的區(qū)別坚芜,一個就是它不需要建立連接墨技,另外就是它在每次收發(fā)的報文都保留了消息的邊界。
  • server端 因為UDP協(xié)議不需要建立連接缔刹,它的過程如下:
    1. 構(gòu)造DatagramSocket實例振湾,指定本地端口杀迹。
    2. 通過DatagramSocket實例的receive方法接收DatagramPacket.DatagramPacket中間就包含了通信的內(nèi)容。
    3. 通過DatagramSocket的send和receive方法來收和發(fā)DatagramPacket.

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPSendTest {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket();

        byte[] buffer = "hello xiaobin".getBytes();
        DatagramPacket dp = new DatagramPacket(buffer,buffer.length, InetAddress.getByName("127.0.0.1"),7879);
        socket.send(dp);
        socket.close();
    }
}


  • client端 UDP客戶端的步驟也比較簡單押搪,主要包括下面3步:
    1. 構(gòu)造DatagramSocket實例树酪。
    2. 通過DatagramSocket實例的send和receive方法發(fā)送DatagramPacket報文。
    3. 結(jié)束后大州,調(diào)用DatagramSocket的close方法關(guān)閉续语。
  • 因為和TCP不同,UDP發(fā)送報文的時候可以在同一個本地端口隨意發(fā)送給不同的服務器厦画,一般不需要在UDP的DatagramSocket的構(gòu)造函數(shù)中指定目的服務器的地址疮茄。

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UDPReceiveTest {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(7879);
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf,buf.length);
        socket.receive(dp);
        System.out.println("host : " + dp.getAddress().getHostAddress()+ " : " + dp.getPort() + " : " + dp.getSocketAddress());
        System.out.println(new String(dp.getData(),0,dp.getLength()));
        socket.close();
    }
}

4. 服務降級

  • 對于RPC服務來說,核心是遠程調(diào)用根暑,服務降級屬于服務治理方面的內(nèi)容力试。
  • 降級方式
    • 手動降級:服務超時超過一定比例后,手動將服務關(guān)閉
    • 自動降級:根據(jù)服務請求的通過率排嫌,自動處理畸裳。通過率 = 成功的請求 / 總請求
  • 服務統(tǒng)計:列表頁的服務在請求時,是按key值進行請求不同的方法躏率,底層去掉用不同的服務獲取數(shù)據(jù)躯畴。因此根據(jù)這個前提條件民鼓,可以實現(xiàn)服務的手動和自動降級
    • 手動降級:根據(jù)服務管理平臺的報警,當調(diào)用底層服務發(fā)生超時或異常時蓬抄,判斷是否需要進行手動處理丰嘉,手動屏蔽相關(guān)的調(diào)用key。
    • 自動降級:在數(shù)據(jù)返回時嚷缭,根據(jù)是否發(fā)生異常判斷服務的成功或失敗情況饮亏,統(tǒng)計服務的通過率,當?shù)讓臃瞻l(fā)生較多異常時阅爽,會自動屏蔽對該key的調(diào)用路幸。
  • 降級實現(xiàn)
    • 手動降級,通過控制調(diào)用key來訪問底層的服務獲取數(shù)據(jù)付翁,key可以通過多種方式傳遞到服務入口:
      • 通過服務接口
      • 通過zk
      • 通過發(fā)送udp命令
      • 其他方式
    • 自動降級简肴,計算服務的通過率可以根據(jù)統(tǒng)計的服務成功量和失敗量來統(tǒng)計,對于降級策略百侧,需要慎重選擇砰识,根據(jù)服務的通過率來設(shè)置一定比例的控制,在自動降級中實現(xiàn)快速失敗佣渴,緩慢升級的原則來處理有問題的服務辫狼。

5. 降級實現(xiàn)

  • 手動降級:通過增加黑名單監(jiān)聽,在服務進行請求時辛润,先查詢屏蔽名單中是否有該服務膨处,根據(jù)判斷結(jié)果進行處理。服務在啟動時砂竖,同時啟動一個監(jiān)聽線程真椿,監(jiān)聽一個端口,當有需要降級的key時乎澄,可以通過發(fā)送udp命令的方式將key發(fā)送過來瀑粥,啟動對該key的降級,服務重啟后失效三圆。定義發(fā)送的upd命令:list、add避咆、clear

  • BlackListListener 創(chuàng)建命令接口

public interface BlackListListener {

    void addAll(List<String> items);

    void removeAll(List<String> items);

    void clear();

    Set<String> list();

    boolean contains(String item);

    boolean isEmpty();
}

  • CommandServer 接收命令的監(jiān)聽方法舟肉,BlackListListener設(shè)置相關(guān)的屏蔽內(nèi)容,服務啟動時初始化該方法查库,直接貼代碼

public class CommandServer extends Thread{

    private static final Logger LOG = LoggerFactory.getLogger(CommandServer.class);
    private DatagramSocket serverSocket;
    volatile boolean running = true;
    private BlackListListener black = BlackListenerService.getInstance();

    public void serverStart() throws SocketException {
        try {
            Config config = new Config(Dict.APP_CONFIG_PROPERTIES);
            int port = ConfigUtil.getPropertyCount(config, "WORK.COMMAND.SERVER.PORT", 9991);
            LOG.info("start a DatagramSocket with port :" + port);
            serverSocket = new DatagramSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void serverStop(){
        this.setDaemon(true);
        this.running = false;
        if (serverSocket != null){
            serverSocket.close();
        }
    }

    public void start(){
        try {
            this.serverStart();
            super.start();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public void run(){
        while (running){
            try {
                byte[] receiveBuff = new byte[4096];
                DatagramPacket dp = new DatagramPacket(receiveBuff, receiveBuff.length);
                serverSocket.receive(dp);
                if (dp.getLength() == 0){
                    continue;
                }else{
                    String receiveStr = new String(dp.getData(), "UTF-8");
                    receiveStr = receiveStr.replace('\n',' ').replace('\r',' ').trim();
                    LOG.info(String.format("input[%s], source ip:[%s]", receiveStr, dp.getAddress()));
                    InetAddress addr = dp.getAddress();
                    int port = dp.getPort();
                    DatagramPacket dpc = output(addr, port, parser(receiveStr));
                    serverSocket.send(dpc);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public String parser(String cmd){
        String backString = "Error command!";
        if (StringUtils.isEmpty(cmd)){
            return backString + "\r\n";
        }
        cmd = cmd.trim();
        if ("list".equals(cmd)) {
            backString = "["+Joiner.on(",").join(black.list())+"]";
        } else if (cmd.startsWith("add ")) {
            cmd = cmd.replaceFirst("add ", "");
            String[] cmdArray = cmd.split("\\s");
            black.addAll(Arrays.asList(cmdArray));
            backString = "["+Joiner.on(",").join(black.list())+"]";
        } else if (cmd.startsWith("remove ")) {
            cmd = cmd.replaceFirst("remove ", "");
            String[] cmdArray = cmd.split("\\s");
            black.removeAll(Arrays.asList(cmdArray));
            backString = "["+Joiner.on(",").join(black.list())+"]";
        } else if (cmd.equalsIgnoreCase("clear")) {
            black.clear();
            backString = "["+Joiner.on(",").join(black.list())+"]";
        } else if(cmd.startsWith("up ")){
            cmd = cmd.replaceFirst("up ", "");
            String[] cmdArray = cmd.split("\\s");
            if (cmdArray.length==0){
                backString = "help:ignore name name";
            }else{
                for(String name: cmdArray){
                    CrossRateManager.getCrossRateManager().ignore(name, false);
                }
                backString = CrossRateManager.getCrossRateManager().list();
            }
        }else if(cmd.startsWith("down ")) {
            cmd = cmd.replaceFirst("down ", "");
            String[] cmdArray = cmd.split("\\s");
            if (cmdArray.length == 0) {
                backString = "help:ignore name name";
            } else {
                for (String name : cmdArray) {
                    CrossRateManager.getCrossRateManager().ignore(name, true);
                }
                backString = CrossRateManager.getCrossRateManager().list();
            }
        }
        backString += "\r\n";
        return backString;
    }

    private DatagramPacket output(InetAddress addr, int port, String text){
        DatagramPacket dp = new DatagramPacket(text.getBytes(), text.getBytes().length, addr, port);
        return dp;
    }

    public static void main(String[] args) {
        CommandServer cs = new CommandServer();
        cs.start();
    }
}

6. 降級意義

  • 根據(jù)線上生產(chǎn)環(huán)境發(fā)生故障的經(jīng)驗路媚,我們對服務進行了統(tǒng)計,按服務的重要性進行分級:基礎(chǔ)信息樊销、擴展信息整慎,在必要時脏款,可以對兩者進行分別降級。

參考:

TCP裤园、UDP撤师、IP 協(xié)議分析-草根老師

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拧揽,隨后出現(xiàn)的幾起案子剃盾,更是在濱河造成了極大的恐慌,老刑警劉巖淤袜,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痒谴,死亡現(xiàn)場離奇詭異,居然都是意外死亡铡羡,警方通過查閱死者的電腦和手機积蔚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烦周,“玉大人尽爆,你說我怎么就攤上這事÷鄯” “怎么了教翩?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長贪壳。 經(jīng)常有香客問我饱亿,道長,這世上最難降的妖魔是什么闰靴? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任彪笼,我火速辦了婚禮,結(jié)果婚禮上蚂且,老公的妹妹穿的比我還像新娘配猫。我一直安慰自己,他們只是感情好杏死,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布泵肄。 她就那樣靜靜地躺著,像睡著了一般淑翼。 火紅的嫁衣襯著肌膚如雪腐巢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天玄括,我揣著相機與錄音冯丙,去河邊找鬼。 笑死遭京,一個胖子當著我的面吹牛胃惜,可吹牛的內(nèi)容都是我干的泞莉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼船殉,長吁一口氣:“原來是場噩夢啊……” “哼鲫趁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捺弦,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤饮寞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后列吼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幽崩,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年寞钥,在試婚紗的時候發(fā)現(xiàn)自己被綠了慌申。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡理郑,死狀恐怖蹄溉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情您炉,我是刑警寧澤柒爵,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站赚爵,受9級特大地震影響棉胀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冀膝,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一唁奢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧窝剖,春花似錦麻掸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疙描,卻和暖如春狂魔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淫痰。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留整份,地道東北人待错。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓籽孙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親火俄。 傳聞我的和親對象是個殘疾皇子犯建,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1.這篇文章不是本人原創(chuàng)的,只是個人為了對這部分知識做一個整理和系統(tǒng)的輸出而編輯成的瓜客,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,075評論 6 174
  • 個人認為适瓦,Goodboy1881先生的TCP /IP 協(xié)議詳解學習博客系列博客是一部非常精彩的學習筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,059評論 0 8
  • 參考:http://www.2cto.com/net/201611/569006.html TCP HTTP UD...
    F麥子閱讀 2,951評論 0 14
  • 1.1 TCP/IP協(xié)議組 TCP/IP協(xié)議(傳輸控制協(xié)議)由網(wǎng)絡層的IP協(xié)議和傳輸層的TCP協(xié)議組成 IP層負責...
    F麥子閱讀 2,791評論 0 25
  • 網(wǎng)絡概念第一天 兩臺電腦怎么通過網(wǎng)絡傳輸數(shù)據(jù)署恍?怎樣才能知道傳輸?shù)氖菙?shù)據(jù)?誰摸過網(wǎng)線蜻直? 看電影盯质,怎么看的?通過電流袭蝗,...
    小吖朱閱讀 1,564評論 0 1