一、網(wǎng)絡編程的基本概念 :
1. 網(wǎng)絡
? ? ? ? 就是將不同區(qū)域的電腦連接到一起,組成局域網(wǎng)、城域網(wǎng)或廣域網(wǎng)。把分部在不同地理區(qū)域的計算機于專門的外部設備用通信線路 互聯(lián)成一個規(guī)模大、功能強的網(wǎng)絡系統(tǒng),從而使眾多的計算機可以方便地互相傳遞信息,共享硬件、軟件、數(shù)據(jù)信息等資源。
2. 計算機網(wǎng)絡?
????????通過傳輸介質(zhì)、通信設施和網(wǎng)絡通信協(xié)議,將地理位置相同的具有獨立功能的多臺計算機及其外部設備連起來,實現(xiàn)資源共享 和數(shù)據(jù)傳輸?shù)南到y(tǒng)。
3. 通信協(xié)議
計算機網(wǎng)路中實現(xiàn)通信必須有一些通信協(xié)議的規(guī)定,對傳輸代碼、代碼結(jié)構(gòu)、傳輸控制步驟出錯控制等制定標準。
4. 通信接口
為了使兩個節(jié)點之間能進行對話,必須在他們之間建立通信工具(即接口),使彼此之間能進行信息交換。
5. 網(wǎng)絡分層
? ? ? ?1. 由于結(jié)點之間聯(lián)系很復雜,在指定協(xié)議時,把復雜成份分解成一些簡單的成份,再將他們復合起來。最常用的復合方式是層次 方式,即同層間可以通信、上一層可以調(diào)用下一層,而與再下一層不發(fā)生關(guān)系
? ? ? ? 2. TCP/IP是一個協(xié)議族,也是按照層次劃分,共四層:應用層,傳輸層,互連網(wǎng)絡層,接口層(物理+數(shù)據(jù)鏈路層)
? ? ? ? 3. OSI網(wǎng)絡通信協(xié)議模型,是一個參考模型,而TCP/IP協(xié)議是事實上的標準。TCP/IP協(xié)議參考了OSI模型,但是并沒有嚴格按照OSI規(guī) 定的七層標準去劃分,而只劃分了四層,這樣會更簡單點,當劃分太多層時,你很難區(qū)分某個協(xié)議是屬于哪個層次的
二、網(wǎng)絡編程三要素?
1. IP地址
????????要想讓網(wǎng)絡中的計算機能夠互相通信,必須為計算機指定一個標識號,通過這個標識號來指定要接受數(shù)據(jù)的計算機和識別發(fā)送 的計算機,而IP地址就是這個標識號,也就是設備的標識。
1.1?IP地址分為兩大類
- IPv4:是給每個連接在網(wǎng)絡上的主機分配一個32bit地址。按照TCP/IP規(guī)定,IP地址用二進制來表示,每個IP地址的 長32bit,也就是4個字節(jié)。
- IPv6:由于互聯(lián)網(wǎng)的蓬勃發(fā)展,IP地址的需求量愈來愈大,但是網(wǎng)絡地址資源有限,使得IP的分配越發(fā)緊張。為了擴 大地址空間,通過IPv6重新定義地址空間,采用128bit地址長度,每16個字節(jié)一組,分成8組十六進制數(shù),這就解決 了網(wǎng)絡地址資源數(shù)量不夠的問題。
1.2 InetAddress類 (在Java中使用InetAddress類代表IP)
????????常用的方法 :
String getHostAddress () | 返回IP地址字符串(以文本表現(xiàn)形式) |
String getHostName () | 返回此IP地址的主機名 |
Byte[] getAddress () | 返回此InetAddress對象的原始IP地址 |
2. 端口
2.1?概念:
????????網(wǎng)絡的通信,本質(zhì)上是兩個應用程序的通信,每臺計算機都有很多的應用程序。IP地址是唯一的標識網(wǎng)絡的設備,端口 號就是唯一標識設備中的應用程序,也就是應用程序的標識。
2.2?端口號:
????????用兩個字節(jié)表示的整數(shù),它的取值范圍是0~65535。其中,0~1023之間的端口號用于一些知名的網(wǎng)絡服務和應用,普通 的應用程序需要使用1024以上的端口號。如果端口號被另外一個服務或應用所占用,會導致當前程序啟動失敗。
2.3?IntetSocketAddress類
????????包含IP和端口信息,常用于Socket通信。此類實現(xiàn)套接字數(shù)字地址(IP地址+端口號),不依賴任何協(xié)議。
????????常用的方法 :
InetAddress getAddress() | 獲得InetAddress |
Int getPort () | 獲取端口號 |
String getHostName() | 獲取主機名 |
三、協(xié)議
????????通過計算機網(wǎng)絡可以使多臺計算機實現(xiàn)連接,位于同一網(wǎng)絡中的計算機進行連接和通信時需要遵守一定的規(guī)則,這就好比在道 路中形勢的汽車一定要遵守交通規(guī)則一樣。在計算機網(wǎng)路中,這些連接和通信的規(guī)則被稱為網(wǎng)絡通信協(xié)議。它對數(shù)據(jù)的傳輸格式、傳 輸速率、傳輸步驟做了統(tǒng)一規(guī)定,通信雙方必須同時遵守才能完成數(shù)據(jù)交換。
3.1 UDP協(xié)議
- 用戶數(shù)據(jù)報協(xié)議(User Datagram Protocol)
- UDP是預無線通信協(xié)議,即在數(shù)據(jù)傳輸時,數(shù)據(jù)的發(fā)送端和接受端不建立邏輯連接。簡單來說,當一臺計算機向另外一臺計算機 發(fā)送數(shù)據(jù)時,發(fā)送端不會確認接受端是否存在,就會發(fā)送出數(shù)據(jù),同樣接受端在收到數(shù)據(jù)時,夜不會向發(fā)送端反饋是否收到數(shù) 據(jù)
- 由于使用UDP協(xié)議消耗資源少,通信效率高,所以通常都會用于音頻、視頻和普通數(shù)據(jù)的傳輸
- 例如視頻會議通常采用UDP協(xié)議,因為這種情況即使偶爾丟失一兩個數(shù)據(jù)包,也不會對接受結(jié)果產(chǎn)生太大影響。但是在使用UDP 協(xié)議傳送數(shù)據(jù)時,由于UDP的面向無連接性,不能保證數(shù)據(jù)的完整性,因此在傳輸重要數(shù)據(jù)時不建議使用UDP協(xié)議。
3.2 TCP協(xié)議
- 傳輸控制協(xié)議(Transmission Control Protocol)
- TCP協(xié)議是面向連接的通信協(xié)議,即傳輸數(shù)據(jù)之前,在發(fā)送端和接受端建立邏輯連接,然后再傳輸數(shù)據(jù),它提供了兩臺計算機之 間可靠無差錯的數(shù)據(jù)連接。在TCP連接中必須明確客戶端于服務端,由于客戶端向服務端發(fā)出連接請求,每次連接的創(chuàng)建都需要 經(jīng)過“三次握手”;
3.3 三次握手
TCP協(xié)議中,在發(fā)送數(shù)據(jù)的準備階段,客戶端與服務器之間的三次交互,以保證連接的可靠性
第一次握手 : 客戶端向服務器發(fā)送連接請求,等待服務器確認
第二次握手 : 服務器向客戶端回送一個響應,通知客戶端收到了連接請求
第三次握手 : 客戶端再次向服務器發(fā)送確認信息,確認連接
????????完成三次握手連接建立后,客戶端和服務器就可以開始進行數(shù)據(jù)傳輸了。由于這種面向連接的特性,TCP協(xié)議可以保證傳輸數(shù)據(jù) 的安全,所以應用非常廣泛。例如上傳文件,下載文件、瀏覽網(wǎng)頁。
3.3.1 TCP通信原理 :
????????TCP通信協(xié)議是一種可靠的網(wǎng)絡協(xié)議,它在通信的兩端各建立一個Socket對象,從而在通信的兩端形成網(wǎng)絡虛擬鏈路,一旦建 立了虛擬的網(wǎng)絡鏈路,兩端的程序就可以通過虛擬鏈路進行通信。
- 使用基于TCP協(xié)議的Socket網(wǎng)絡編程實現(xiàn),使用Socket對象來代表兩端的通信端口
- TCP協(xié)議基于請求-響應模式,第一次主動發(fā)起的程序被客戶端(Client)程序
- 第一次通訊中等待連接的程序被服務器(Serser)程序
- 利用IO流實現(xiàn)數(shù)據(jù)的傳輸
四、TCP實現(xiàn)步驟(聊天案例)
1. 步驟
1、在服務端指定一個端口號來創(chuàng)建ServerSocket,并使用accept方法進行偵聽,這將阻塞服務器線程,等待用戶請求。
2、在客戶端指定服務的主機IP和端口號來創(chuàng)建socket,并連接服務端ServerSocket,此時服務端accept方法被喚醒,同時返回一個 和客戶端通信的socket。
3、在客戶端和服務端分別使用socket來獲取網(wǎng)絡通信輸入/輸出流,并按照一定的通信協(xié)議對socket進行讀/寫操作。
4、通信完成后,在客戶端和服務端中分別關(guān)閉socket。
2. 服務器端
- 創(chuàng)建ServerSocket(int port)對象????????
- 在Socket上使用accept方法監(jiān)聽客戶端的連接請求(阻塞等待連接功能)
- 接受并處理請求信息 ? 將處理結(jié)果返回給客戶端
- 關(guān)閉流和Socket對象
3. 客戶端
- 創(chuàng)建Socket(Strng host , int port)對象
- 向服務器發(fā)送連接請求 ? 向服務端發(fā)送服務請求 ? 接受服務結(jié)果(服務響應)
- 關(guān)閉流和Socket對象
4. ServerSocket類
常用構(gòu)造器 : ServerSocket(int port) 創(chuàng)建綁定到指定端口的服務器套接字
常用方法 :Socket accept() 偵聽要連接到此套接字并接受它
Java為客戶端提供了Socket類,為服務器端提供了ServerSocket類
構(gòu)造方法:
Socket(InetAddress address , int port)address(IP地址), port(端口號)
創(chuàng)建流套接字并將其連接到指定IP地址的指定端口號;
常用方法 :
OutoutStream getOutputStream() | 返回套接字的輸出流 |
InputStream getInputStream () | 返回套接字的輸入流 |
Void shutdownOutput() | 禁用套接字的輸出流? |
5. 利用實現(xiàn)客戶端于服務器無線聊天功能
1. 服務器
package com.net;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
* 服務器
* @author 云村小威
*
* @2023年7月19日 下午10:02:11
*/
public class Server {
public static void main(String[] args) throws Exception {
System.out.println("??????服務端??????");
/* 創(chuàng)建服務器連接對象 */
ServerSocket ss = new ServerSocket(6666);
System.out.println("服務器已開啟,等待連接...");
/* 調(diào)用accept方法,客服端沒有啟動連接不能執(zhí)行下一步(阻塞功能) */
Socket server = ss.accept();
System.out.println("客戶端連接成功");
/* 獲取輸入流,讀取客戶端發(fā)送的數(shù)據(jù) */
InputStream inputStream = server.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
/* 獲取輸出流,向客戶端回寫數(shù)據(jù) */
Scanner zw = new Scanner(System.in);
OutputStream outputStream = server.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
while (true) {
String readLine = br.readLine();
System.out.println("客戶端 :" + readLine);
if ("拜拜".equals(readLine)) {
System.out.println("再見");
break;
}
System.out.println("請輸入發(fā)送到客戶端的內(nèi)容:");
String test = zw.next();
/* 向客戶端寫入內(nèi)容 */
bw.write(test);
bw.newLine();
bw.flush();
if ("拜拜".equals(test)) {
System.out.println("再見");
break;
}
}
/* 關(guān)閉資源 */
bw.close();
outputStream.close();
br.close();
inputStream.close();
server.close();
ss.close();
}
}
2. 客戶端
package com.net;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
/**
* 客戶端
* @author 云村小威
*
* @2023年7月19日 下午10:02:00
*/
public class Client {
public static void main(String[] args) throws Exception {
System.out.println("?????客戶端?????");
/* 創(chuàng)建Socket對象,請求連接 */
Socket client = new Socket(InetAddress.getByName("127.0.0.1"), 6666);
System.out.println("服務器連接成功...");
/* 獲取輸出流對象,向服務器寫入數(shù)據(jù) */
OutputStream outputStream = client.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
/* 獲取輸入流對象,讀取服務器數(shù)據(jù) */
InputStream inputStream = client.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
/* 向服務器發(fā)送信息 */
Scanner zw = new Scanner(System.in);
while (true) {
System.out.println("請輸入發(fā)送到服務器的內(nèi)容:");
String test = zw.next();
/* 向服務器寫入內(nèi)容 */
bw.write(test);
bw.newLine();
bw.flush();
if ("拜拜".equals(test)) {
System.out.println("再見");
break;
}
/* 每次讀取一個字節(jié)數(shù)組 */
String content = br.readLine();
System.out.println("服務器 : " + content);
if ("拜拜".equals(content)) {
System.out.println("再見");
break;
}
}
/* 關(guān)閉資源 */
br.close();
inputStream.close();
bw.close();
outputStream.close();
client.close();
}
}
3. 控制臺版 效果
文章來源:http://www.zghlxwxcb.cn/news/detail-594971.html
? ? 感謝您的觀看,我會在本專欄持續(xù)更新,后續(xù)更新多線程等知識。接下來就可以利用多線程實現(xiàn)窗體實時無線聊天功能,請點擊進入JAVA多線程?!???????文章來源地址http://www.zghlxwxcb.cn/news/detail-594971.html
到了這里,關(guān)于.NET網(wǎng)絡編程——TCP通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!