「網絡基礎」網絡套接字、端口、IP、協議、TCP與UDP,一樣都沒少

「網絡基礎」網絡套接字、端口、IP、協議、TCP與UDP,一樣都沒少

網絡編程


網絡套接字

源IP地址和目的IP地址以及源端口號和目的端口號的組合稱為網絡套接字,用於標識客戶端請求的服務器和服務;應用程序可以通過套接字打開、讀寫、關閉數據,允許應用程序在網絡中加入I\\O,與網絡中的其他應用程序進行通信。

傳輸層實現端到端的通信,每個傳輸層連接有兩個端點,那麼,這個連接的端點是什麼呢?既不是主機的IP地址,也不是某個應用進程,更也不是傳輸層的協議端口;而是套接字(socket)。每一個傳輸層連接唯一地被通信兩端的兩個端點(即兩個套接字)所確定。

「網絡基礎」網絡套接字、端口、IP、協議、TCP與UDP,一樣都沒少

ipv6

根據RFC793的定義:IP地址和端口號組合起來就構成了套接字。套接字,實際上是一個通信端點,每個套接字都有一個套接字序號,包括主機的IP地址與一個16位的主機端口號,展現形式是點分十進制的IP地址後面寫上端口號,中間用冒號或逗號隔開,即:主機IP地址:端口號,比如,113.301.151.231:23就是一個套接字。

兩個應用程序之間的數據傳輸要通過套接字來完成。當兩個網絡應用程序進行通信時,其中的一個網絡應用程序將要傳輸的信息寫入它所在主機的Socket中,然後該Socket通過網絡接口卡的傳輸介質將這段信息發送給另一臺主機的Socket中,使這段信息能傳送到其他程序中。

TCP/IP的核心內容被封裝在操作系統中,並向外提供了編程接口,如果應用程序要使用TCP/IP,可以通過系統提供的TCP/IP的編程接口來實現。在Windows環境下,網絡應用程序編程接口稱作Windows Socket,Linux 下Linux socket API存在頭文件sys/socket.h中。


網絡編程

通過調用套接字接口來實現進程間通信的程序設計就是網絡編程。利用網絡編程便可以實現同一系統中不同進程之間的通信,更是可以通過網絡連接實現不同系統中多個進程的通信,比如:QQ 、微信等。

也正是因為網絡編程的出現,才能實現現如今大型網絡遊戲的多人競技,若是沒有網絡,遊戲再怎麼發展也只是單機遊戲。


網絡編程三要素

  1. IP地址:能夠確定是哪一臺主機
  2. 端口號:能夠確定主機上的某個進程
  3. 網絡通信協議:制定網絡通信、數據交互的規則


Java 中的網絡編程:java 對網絡編程也提供了很好的支持,java 中關於網絡編程的api位於java.net包下。

網絡基礎

「網絡基礎」網絡套接字、端口、IP、協議、TCP與UDP,一樣都沒少

IP 協議

IP,即Internet Protocol,網際互連協議的縮寫,簡稱“網協”;是TCP/IP體系中的網絡層協議,為計算機網路互連通信而設計,IP地址具有唯一性。

IP地址根據網絡通訊協議的不同,有IPv4和IPv6兩種:

  • IPv4:網際協議版本4(全稱 Internet Protocol version 4,簡稱IPv4),又稱互聯網通信協議第四版,比如:192.168.0.7
  • IPv6:互聯網協議第6版,全稱 Internet Protocol Version 6,簡稱IPv6,是互聯網工程任務組(IETF)為替代IPv4而設計的下一代IP協議,其地址數量號稱可以為全世界的每一粒沙子編上一個地址,地址比如:1080:0:0:0:8:800:200C:417A


IP地址編址方案,IP地址編址方案將IP地址空間劃分為A、B、C、D、E五類,其中A、B、C是基本類,D、E類作為多播和保留使用。

  • A類: 10.0.0.0 -- 10.255.255.255
  • B類:172.16.0.0 -- 172.31.255.255
  • C類: 192.168.0.0 -- 192.168.255.255
  • D類:組播地址,224.0.0.0~239.255.255.255,這個範圍內的每個IP地址,都代表一組特定的主機


本機IP地址

  • 127.0.0.1
  • localhost


Java 中的IP地址

在Java中,使用InetAddress類來表示IP地址,InetAddress類有兩個子類:Inet4Address類 和 Inet6Address類,分別對應IPv4和IPv6。

「網絡基礎」網絡套接字、端口、IP、協議、TCP與UDP,一樣都沒少

Java 中的IP地址

InetAddress類的使用也很簡單,demo如下所示:

<code>public class InetAddressDemo {

public static void main(String[] args) throws Exception {

InetAddress ip = InetAddress.getLocalHost();
System.out.println("ip: " + ip.toString());
System.out.println("hostName: " + ip.getHostName());
System.out.println("hostAddress: " + ip.getHostAddress());
System.out.println("localHost: " + InetAddress.getLocalHost());
System.out.println("isReachable: " + InetAddress.getLocalHost().isReachable(1000));

}

}/<code>

上述demo運行結果如下所示:

<code>ip: SHISAN-WIN10/192.168.44.1
hostName: SHISAN-WIN10
hostAddress: 192.168.44.1
localHost: SHISAN-WIN10/192.168.44.1
isReachable: true/<code>


端口(port)

端口,英文port的中文名稱,常見於各類網絡技術文檔,可以認為是設備與外界通訊交流的出口。端口可分為虛擬端口物理端口,虛擬端口指計算機內部或交換機路由器內的端口,對普通用戶不可見,例如計算機中的80、21、23等端口;而物理端口是位於設備外部的可見端口,比如電腦主機的RJ45網口,交換機、路由器、集線器等的RJ45端口,電話使用的RJ11插口等都屬於物理接口。


協議端口

如果把IP地址比作一棟建築,端口就是出入這棟建築的門,建築可以有多個門;同理,IP地址的端口也可以有多個,而且會比門的數量多得多,因為一個IP地址的端口可以有65536(65536 = 2^16)個之多;端口是通過端口號來標記的,端口號只有整數,範圍是從0 到65535(2^16-1),共計65536個。因此,端口的使用需要注意:

  • 在同一個計算機系統中,端口不能重複;若端口重複,會引發端口衝突而導致系程序運行錯誤;
  • 在開發中,經常會自定義端口,在自定義端口時儘量選擇10000以後的,避免和系統現有的程序衝突;


協議

協議(protocol),全稱是網絡協議,是要通信的計算機雙方必須共同遵從的一組約定,如怎樣建立連接、通信雙方如何互相識別、如何保證通信的順利完成等,

網絡通信協議的三要素:語法、語義、時序。只有雙方都按照通信規則建立連接,通信才能完成。

  1. 語法:協議中數據和要傳輸的信息的結構或格式;
  2. 語義:發出何種控制信息,可以完成何種動作,又會做出何種響應;
  3. 時序(同步):即事件實現順序的詳細說明。


網絡模型各層中的網絡協議:

「網絡基礎」網絡套接字、端口、IP、協議、TCP與UDP,一樣都沒少

網絡模型各層中的網絡協議

下面是一些常見的網絡協議:

  • http:超文本傳輸協議資源,基本所有面向用戶的網絡應用都是使用http協議進行通信的
  • https:用安全套接字層傳送的超文本傳輸協議
  • ftp :文件傳輸協議
  • mailto:電子郵件地址
  • file:當地電腦或網上分享的文件,當我們用瀏覽器打開本地文件時便會看到這個協議


MIME 編碼

在因特網上有很多的不同類型的資源,HTTP協議要為每種類型的資源打上於是MIME類型標籤,依此來描述其傳輸的資源類型。

MIME,全稱是Multipurpose Internet Mail Extension,即“多用途因特網郵件擴展”,最初的設計是為了解決在不同的電子郵件系統之間來回搬移報文時存在的問題,但由於其出色的表現,所以,在HTTP 協議中也繼續使用,使用其來標記資源文件類型。

MIME 類型是一種文本標記,其內容由一種主要的資源類型和一個子類型組成,中間使用“/”分隔。在HTTP協議中使用首部中的Content-type字段來表示,常見的MIME類型有數百個,以下是一些常見的:

  • text/html:表示html格式的文本文檔;
  • text/plain:表示ASCII格式的文本文檔;
  • image/jpeg:表示jpeg格式的圖片;
  • image/gif:表示gif格式的圖片;
  • video/quicktime:表示apple的QuickTime電影類型;
  • application/vnd.ms-powerpoint:表示微軟的ppt文檔;


URI、URL、URI

URI:統一資源標識符(Uniform Resource Identifier,簡稱URI),是一個用於標識聯網資源名稱的字符串,能夠在世界範圍內唯一標識某一資源。URI有兩種形式,即URL和URN。

URL:統一資源定位符,是資源標識符最常見的形式,用於定位某一互聯網上的資源,是對可以從互聯網上得到的資源的位置和訪問方法的一種簡潔的表示,使用URL可以明確說明如何從一個精確、固定的位置獲取資源。

大部分的URL,都是由三部分組成:

  1. scheme:這裡通常是協議頭,如:http,https;
  2. 服務器地址:服務器地址一般指的就是我們常說的域名,比如:baidu.com;
  3. 資源位置:跟在域名之後的部分,比如:/index,其指定了服務器上的某個資源;

互聯網上的每個資源都有一個唯一的URL,它會指出文件的位置以及客戶端的處理方式,現在幾乎所有的URI都是URL,所以,平常所說的URI指的就是URL。


URN:統一資源名,URN是作為特定內容的唯一名稱使用的,而且與資源所在的位置無關,因此,使用URN,就不必擔心因資源遷移而導致無法訪問的問題。此外,還可以使用同一個名稱通過多種網絡協議來訪問資源。

比如:urn:ietf:rfc:2141 可以用來命名RFC 2141文檔,而不閉擔心其位於何處。


TCP、UDP

在傳輸層中的TCP協議和UDP協議在網絡編程會經常使用到,下面就來介紹介紹:

  • TCP :面向連接(經歷三次握手)、傳輸可靠(保證數據正確性,保證數據順序)、用於傳輸大量數據(流模式)、速度慢,建立連接需要開銷較多(時間,系統資源)。 工作模式在服務端和客戶端之間進行。
  • UDP:面向非連接、傳輸不可靠(容易發生丟包[,導致數據丟失)、用於傳輸少量數據(數據報包模式)、速度快。工作模式在發送端和接收端客戶端之間進行。


在所有的網絡編程語言中都提供了對TCP協議和UDP協議的支持,Java 同樣也不例外,下面就通過兩個demo來展示:

Java 中的TCP

服務端:Server.java

<code>public class Server {

public static void main(String[] args) throws Exception {
String data = "我是tcp的服務端";

// 創建TCP服務端,指定端口為8888
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服務端已就緒!");
// 允許客戶端建立連接
boolean accept = true;
while (accept) {
Socket client = serverSocket.accept();
System.out.println("客戶端 : " + client.getInetAddress() + " 已連接。");
// 通過客戶端的輸出流,給客戶端輸出數據
PrintStream print = new PrintStream(client.getOutputStream());
print.println(data);
print.close();
}
serverSocket.close();
}

}/<code>


客戶端:Client.java

<code>public class Client {

public static void main(String[] args) throws Exception {
// 穿件客戶端,與服務端建立連接
Socket client = new Socket("localhost", 8888);
// 輸出服務端輸入的數據
Scanner scanner = new Scanner(client.getInputStream());
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
scanner.close();
client.close();
}

}/<code>


記得要先運行服務端,再運行客戶端。不然,會有意想不到的結果哦。


Java 中的UDP

發送端:Send.java

<code>public class Send {

public static void main(String[] args) throws Exception {
String data = "我是udp的發送端";
// 創建發送端,端口為13000
DatagramSocket sender = new DatagramSocket(13000);
// 發送數據
DatagramPacket dp = new DatagramPacket(
data.getBytes(), // 發送的數據
data.getBytes().length, // 發送的數據的長度
InetAddress.getLocalHost(), // 接收端的ip
14000); // 接收端的端口

sender.send(dp);
sender.close();

}
}/<code>


接收端:Receive.java​

<code>public class Receive {

public static void main(String[] args) throws Exception {

// 床架接收端對象
DatagramSocket receiver = new DatagramSocket(14000);
byte[] buffer = new byte[1024];
// 接收數據
DatagramPacket dp = new DatagramPacket(buffer, 1024);
receiver.receive(dp);
// 打印接收到的數據
String msg = new String(dp.getData(), 0, dp.getLength());
System.out.println("接收到的數據:" + msg);
}

}/<code>

先運行接收端,再運行發送端即可。


完結。老夫雖不正經,但老夫一身的才華


分享到:


相關文章: