<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          終于把 TCP 協(xié)議與 UDP 協(xié)議給整明白了!

          共 8472字,需瀏覽 17分鐘

           ·

          2021-06-17 20:47

          公眾號(hào)關(guān)注“程序IT圈”,
          選擇“星標(biāo)”,重磅干貨,第一時(shí)間送達(dá)!

          網(wǎng)絡(luò)編程有三個(gè)要素,分別是IP地址、端口號(hào)和通信協(xié)議,那本文主要講述的是TCP與UDP這兩種通信協(xié)議,以及編程的實(shí)現(xiàn)。

          首先,我們需要了解一下IP地址、端口號(hào)、通信協(xié)議的相關(guān)知識(shí)。

          一、IP地址

          網(wǎng)絡(luò)中的計(jì)算機(jī)使用IP地址來進(jìn)行唯一標(biāo)識(shí),IP地址有IPv4和IPv6兩種類型。IPv4采用十進(jìn)制或二進(jìn)制表示形式,十進(jìn)制是一種比較常用的表示形式,如192.168.1.131,IPv6采用十六進(jìn)制表示形式,一般不常用。

          如何查看IP地址相關(guān)信息:

          在Windows系統(tǒng)下,打開cmd,輸入命令ipconfig,按回車即可查看。在Linux或Mac系統(tǒng)下,打開終端,使用ifconfig命令,按回車即可查看。

          二、端口號(hào)

          端口號(hào)是計(jì)算機(jī)中的應(yīng)用程序的一個(gè)整數(shù)數(shù)字標(biāo)號(hào),用來區(qū)分不同的應(yīng)用程序。

          0 ~ 1024 為被系統(tǒng)使用或保留的端口號(hào),0 ~ 65535為有效的端口號(hào),也就是說我們要對(duì)一些程序定義端口號(hào)的時(shí)候,要選擇1024 ~ 65535范圍內(nèi)的整數(shù)數(shù)字。

          比如,以前學(xué)過的MySQL的端口號(hào)是3306,SQLServer的端口號(hào)是1433,查了一下Oracle的端口號(hào)是1521。

          一定要把這些數(shù)據(jù)庫對(duì)應(yīng)的端口號(hào),藏在深深的腦海里,以后在連接數(shù)據(jù)庫的時(shí)候,會(huì)使用到端口號(hào)。

          三、通信協(xié)議

          說的通俗一點(diǎn),通信協(xié)議就是網(wǎng)絡(luò)通信中的規(guī)則,分為TCP協(xié)議和UDP協(xié)議兩種。

          第一種:TCP協(xié)議

          英文名:Transmission Control Protocol

          中文名:傳輸控制協(xié)議

          協(xié)議說明:TCP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。

          舉例:打電話,需要雙方都接通,才能進(jìn)行對(duì)話

          特點(diǎn):效率低,數(shù)據(jù)傳輸比較安全

          第二種:UDP協(xié)議

          英文名:User Datagram Protocol

          中文名:數(shù)據(jù)報(bào)協(xié)議

          關(guān)注公眾號(hào):前端技術(shù)編程,回復(fù)前端,領(lǐng)取資料。

          協(xié)議說明:UDP是一種面向無連接的傳輸層通信協(xié)議。

          舉例:發(fā)短信,不需要雙方建立連接,But,數(shù)據(jù)報(bào)的大小應(yīng)限制在64k以內(nèi)

          特點(diǎn):效率高,數(shù)據(jù)傳輸不安全,容易丟包

          四、三要素關(guān)系圖與網(wǎng)絡(luò)模型圖

          1、網(wǎng)絡(luò)編程三要素關(guān)系圖

          注:圖中端口號(hào)、IP地址為演示,并非真實(shí)

          2、OSI參考模型與TCP/IP參考模型

          五、TCP編程

          TCP是基于字節(jié)流的傳輸層通信協(xié)議,所以TCP編程是基于IO流編程。

          對(duì)于客戶端,我們需要使用Socket類來創(chuàng)建對(duì)象。對(duì)于服務(wù)器端,我們需要使用ServerSocket來創(chuàng)建對(duì)象,通過對(duì)象調(diào)用accept()方法來進(jìn)行監(jiān)聽是否有客戶端訪問。

          客戶端與服務(wù)器端圖解:

          客戶端與服務(wù)器端實(shí)現(xiàn)步驟:

          前提:創(chuàng)建一個(gè)項(xiàng)目,在項(xiàng)目中創(chuàng)建兩個(gè)模塊(model),一個(gè)模塊用來放客戶端相關(guān)代碼,一個(gè)模塊用來放服務(wù)器端相關(guān)代碼。

          目錄結(jié)構(gòu)如下圖

          客戶端:

          1、創(chuàng)建Socket對(duì)象,并指定服務(wù)器端應(yīng)用程序的端口號(hào)和服務(wù)器端主機(jī)的IP地址。

          2、使用Socket的對(duì)象調(diào)用getOutputStream()方法來獲取字節(jié)輸出流對(duì)象。

          3、調(diào)用字節(jié)輸出流的write(byte[] buf)或者write(int b)向服務(wù)器發(fā)送指定數(shù)據(jù)。

          4、記得關(guān)閉流。

          服務(wù)器端:

          1、創(chuàng)建ServerSocket對(duì)象,并指定該應(yīng)用程序的端口號(hào),端口號(hào)必須和客戶端指定的端口號(hào)一樣。

          2、使用ServerSocket對(duì)象的accept()方法來監(jiān)聽客戶端發(fā)送過來的請(qǐng)求,返回值為Socket對(duì)象。

          3、調(diào)用Socket對(duì)象的getInputStream()方法獲取字節(jié)輸入流對(duì)象

          4、調(diào)用字節(jié)輸入流對(duì)象的read(byte[] buf)或read()方法獲取數(shù)據(jù)。

          5、記得關(guān)閉流。

          實(shí)例:

          客戶端向服務(wù)器端發(fā)送信息,并顯示在服務(wù)器端。

          Client類(客戶端)

          package cn.tkrnet.client;

          import java.io.IOException;
          import java.io.OutputStream;
          import java.net.Socket;

          public class Client {
              public static void main(String[] args) throws IOException {

                  //創(chuàng)建Socket對(duì)象,指定要發(fā)送到服務(wù)器端的IP地址,以及服務(wù)器端應(yīng)用程序接收的端口號(hào)
                  //localhost代表本機(jī)IP地址
                  Socket client = new Socket("localhost",9000);

                  //獲取輸出流,用于向服務(wù)器端發(fā)送數(shù)據(jù)
                  OutputStream os = client.getOutputStream();

                  os.write("Java is my friend !".getBytes());
                  System.out.println("信息已發(fā)送");

                  //關(guān)閉流
                  os.close();
                  client.close();
              }
          }

          Server類(服務(wù)器端)

          package cn.tkrnet.server;

          import java.io.IOException;
          import java.io.InputStream;
          import java.net.ServerSocket;
          import java.net.Socket;

          public class Server {
              public static void main(String[] args) throws IOException {
                  System.out.println("--服務(wù)器端已開啟--");

                  //創(chuàng)建ServerSocket對(duì)象,這里的端口號(hào)必須與客戶端的端口號(hào)相同
                  ServerSocket server = new ServerSocket(9000);

                  //調(diào)用方法accept(),用來監(jiān)聽客戶端發(fā)來的請(qǐng)求
                  Socket socket = server.accept();

                  //獲取輸入流對(duì)象
                  InputStream is = socket.getInputStream();

                  //讀取輸入流中的數(shù)據(jù)
                  int b = 0;
                  while ((b =is.read()) != -1){
                      System.out.print((char)b);
                  }
                  //關(guān)閉流
                  is.close();
                  socket.close();
                  server.close();
              }
          }

          提示:在運(yùn)行程序時(shí),一定要先運(yùn)行服務(wù)器端的程序代碼,再運(yùn)行客戶端的程序代碼。因?yàn)榭蛻舳艘蚍?wù)器發(fā)送請(qǐng)求,前提是服務(wù)器端要處于開啟狀態(tài)。

          Server類(服務(wù)器端)運(yùn)行結(jié)果:

          --服務(wù)器端已開啟--

          Client類(客戶端)運(yùn)行結(jié)果:

          信息已發(fā)送

          Client類(客戶端)運(yùn)行后,Server類(服務(wù)器端)收到信息,運(yùn)行結(jié)果:

          --服務(wù)器端已開啟--
          Java is my friend !

          實(shí)例分析:

          服務(wù)器端啟動(dòng)后,服務(wù)器端的accept()方法一直處于監(jiān)聽狀態(tài),直到客戶端連接了服務(wù)器,服務(wù)器端再從流中讀取客戶端發(fā)來的數(shù)據(jù)。

          恕我直言,這是一個(gè)超級(jí)無敵簡(jiǎn)單的單向通信實(shí)例。

          六、UDP編程

          UDP使用數(shù)據(jù)報(bào)進(jìn)行數(shù)據(jù)傳輸,沒有客戶端與服務(wù)器端之分,只有發(fā)送方與接收方,兩者哪個(gè)先啟動(dòng)都不會(huì)報(bào)錯(cuò),但是會(huì)出現(xiàn)數(shù)據(jù)丟包現(xiàn)象。發(fā)送的內(nèi)容有字?jǐn)?shù)限制,大小必須限制在64k以內(nèi)。

          發(fā)送方與接收方實(shí)現(xiàn)步驟:

          前提:創(chuàng)建一個(gè)項(xiàng)目,在項(xiàng)目中創(chuàng)建兩個(gè)模塊(model),一個(gè)模塊用來放發(fā)送方相關(guān)代碼,一個(gè)模塊用來放接收方相關(guān)代碼。

          目錄結(jié)構(gòu)如下圖

          發(fā)送方:

          1、創(chuàng)建DatagramSocket對(duì)象,可以指定應(yīng)用程序的端口號(hào),也可以不指定。
          2、準(zhǔn)備需要發(fā)送的數(shù)據(jù)
          3、創(chuàng)建DatagramPacket對(duì)象,用來對(duì)發(fā)送的數(shù)據(jù)進(jìn)行打包,需要指定發(fā)送內(nèi)容、發(fā)送多少、發(fā)送到哪里和接收方的端口號(hào)四個(gè)參數(shù)。
          4、調(diào)用DatagramSocket對(duì)象的send()方法發(fā)送數(shù)據(jù)。
          5、記得關(guān)閉流。

          接收方:

          1、創(chuàng)建DatagramSocket對(duì)象,指定接收方的端口號(hào),這個(gè)必須指定。
          2、創(chuàng)建一個(gè)byte類型數(shù)組,用來接收發(fā)送方發(fā)送過來的數(shù)據(jù)。
          3、創(chuàng)建DatagramPacket對(duì)象,準(zhǔn)備接收數(shù)據(jù)。
          4、調(diào)用DatagramSocket對(duì)象的receive()方法用于接收數(shù)據(jù)。
          5、使用String類的構(gòu)造方法將byte類型的數(shù)組中的數(shù)據(jù)轉(zhuǎn)化成String類型并顯示。
          6、記得關(guān)閉流。

          實(shí)例:

          發(fā)送方發(fā)送信息,接收方接收信息,并顯示。

          Sender類(發(fā)送方)

          package cn.tkrnet.Sender;

          import java.io.IOException;
          import java.net.*;

          public class Sender {
              public static void main(String[] args) throws IOException {

                  //創(chuàng)建接受或發(fā)送的數(shù)據(jù)報(bào)套接字,并指定發(fā)送方的端口號(hào)為7770
                  DatagramSocket ds = new DatagramSocket(7770);   //端口號(hào)也可以不指定
                  System.out.println("---發(fā)送方---");

                  //創(chuàng)建數(shù)據(jù)報(bào)對(duì)象,用來發(fā)送數(shù)據(jù)
                  byte[] b = "Java is my friend !".getBytes();

                  //8800為接收方的端口號(hào),netAddress.getByName("localhost")是獲取主機(jī)的IP地址
                  DatagramPacket dp = new DatagramPacket(b,b.length, InetAddress.getByName("localhost"),7788);

                  ds.send(dp);    //發(fā)送數(shù)據(jù)報(bào)
                  System.out.println("數(shù)據(jù)已發(fā)送");
                  //關(guān)閉流
                  ds.close();
              }
          }

          Receiver類(接收方)

          package cn.tkrnet.receiver;

          import java.io.IOException;
          import java.net.DatagramPacket;
          import java.net.DatagramSocket;

          public class Receiver {
              public static void main(String[] args) throws IOException {
                  System.out.println("---接收方---");

                  //創(chuàng)建數(shù)據(jù)報(bào)套接字對(duì)象,指定的端口號(hào)要和發(fā)送方發(fā)送數(shù)據(jù)的端口號(hào)相同
                  // (不是發(fā)送方的端口號(hào)7770,是發(fā)送方發(fā)送數(shù)據(jù)的端口號(hào)7788)
                  DatagramSocket ds = new DatagramSocket(7788);

                  //創(chuàng)建接收數(shù)據(jù)報(bào)的對(duì)象
                  byte[] b = new byte[1024];
                  DatagramPacket dp = new DatagramPacket(b,b.length);

                  //接收數(shù)據(jù)
                  ds.receive(dp);
                  System.out.println(new String(b,0,dp.getLength()));
                  //關(guān)閉流
                  ds.close();
              }
          }

          提示:在運(yùn)行程序時(shí),先運(yùn)行發(fā)送方程序,還是先運(yùn)行接收方程序都不會(huì)報(bào)錯(cuò),但是有可能會(huì)出現(xiàn)數(shù)據(jù)丟包,一般我們都先運(yùn)行接收方的程序代碼,再運(yùn)行發(fā)送方的程序代碼。

          Receiver類(接收方)運(yùn)行結(jié)果:

          ---接收方---

          Sender類(發(fā)送方)運(yùn)行結(jié)果:

          ---發(fā)送方---
          數(shù)據(jù)已發(fā)送

          Sender類(發(fā)送方)運(yùn)行后,Receiver類(接收方)接收到信息,運(yùn)行結(jié)果:

          ---接收方---
          Java is my friend !

          實(shí)例分析:

          只有接收方先啟動(dòng)運(yùn)行,才會(huì)存在端口號(hào)為7788的程序,發(fā)送方才能發(fā)送數(shù)據(jù)到指定端口號(hào)7788,接收方才能接收數(shù)據(jù)。

          不瞞你說,這也是個(gè)超級(jí)無敵簡(jiǎn)單的單向通信實(shí)例。

          七、總結(jié)

          以上是我分享給大家的關(guān)于網(wǎng)絡(luò)通信TCP協(xié)議與UDP協(xié)議的一些總結(jié)。如果覺得還不錯(cuò)的話,就送我一個(gè)贊或者在看吧!如果本文對(duì)你有用的話,也歡迎轉(zhuǎn)發(fā)收藏哦!

          來源:https://blog.csdn.net/m0_47890251/

          推薦閱讀

          已上岸青椒關(guān)于復(fù)旦事件的反思

          這100 個(gè)網(wǎng)絡(luò)基礎(chǔ)知識(shí),看完成半個(gè)網(wǎng)絡(luò)高手

          華為天才少年造出自動(dòng)駕駛單車!網(wǎng)友:臥槽,太牛逼了!

          常用 Linux 軟件匯總,足夠用了?。?!

          牛逼黑客是如何攻破一個(gè)網(wǎng)站的?

          10 常見網(wǎng)站安全攻擊手段及防御方法

          2T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,人工智能,考研,軟考,英語,等等。在公眾號(hào)內(nèi)回復(fù)「資源」,即可免費(fèi)獲??!回復(fù)「社群」,可以邀請(qǐng)你加入讀者群!


          ??給個(gè)「在看」,是對(duì)我最大的支持??
          瀏覽 57
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲欧美动漫中文字幕 | 在线中文字幕网站 | SM无码 | 95嫩模主播酒店约 | 三级片www|