Java 全面掌握網(wǎng)絡(luò)編程篇
計(jì)算機(jī)網(wǎng)絡(luò)
是指將地理位置不同的具有獨(dú)立功能的多臺(tái)計(jì)算機(jī)及其外部設(shè)備,通過(guò)通信線(xiàn)路連接起來(lái),在網(wǎng)絡(luò)操作系統(tǒng),網(wǎng)絡(luò)管理軟件及網(wǎng)絡(luò)通信協(xié)議的管理和協(xié)調(diào)下,實(shí)現(xiàn)資源共享和信息傳遞的計(jì)算機(jī)系統(tǒng)。包括局域網(wǎng)(intranet)和廣域網(wǎng)(internet)
網(wǎng)絡(luò)模型
網(wǎng)絡(luò)模型一般是指
○ OSI(Open System Interconnection開(kāi)放系統(tǒng)互連)參考模型
○ TCP/IP參考模型
網(wǎng)絡(luò)編程 就是用來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)互聯(lián)的不同計(jì)算機(jī)上運(yùn)行的程序間可以進(jìn)行數(shù)據(jù)交換。
計(jì)算機(jī)網(wǎng)絡(luò)之間以何種規(guī)則進(jìn)行通信,就是網(wǎng)絡(luò)模型研究問(wèn)題

客戶(hù)機(jī)服務(wù)器模式(Client/Server)
●為了實(shí)現(xiàn)兩臺(tái)計(jì)算機(jī)的通信,必須要用一個(gè)網(wǎng)絡(luò)線(xiàn)路連接兩臺(tái)計(jì)算機(jī)。
● 服務(wù)器(Server)是指提供信息的計(jì)算機(jī)或程序
●客戶(hù)機(jī)(Client)是指請(qǐng)求信息的計(jì)算機(jī)或程序
●網(wǎng)絡(luò)用于連接服務(wù)器與客戶(hù)機(jī),實(shí)現(xiàn)兩者相互通信。

TCP/IP的概念和實(shí)現(xiàn)
TCP/IP:Transmission Control Protocol/Internet Protocol的簡(jiǎn)寫(xiě)。TCP 是傳輸控制協(xié)議的縮寫(xiě),它保障了兩個(gè)應(yīng)用程序之間的可靠通信。通常用于互聯(lián)網(wǎng)協(xié)議,被稱(chēng) TCP / IP。
TCP三次握手(Three-way handshake)
所謂的“三次握手”即對(duì)每次發(fā)送的數(shù)據(jù)量是怎樣跟蹤進(jìn)行協(xié)商使數(shù)據(jù)段的發(fā)送和接收同步,根據(jù)所接收到的數(shù)據(jù)量而確定的數(shù)據(jù)確認(rèn)數(shù)及數(shù)據(jù)發(fā)送、接收完畢后何時(shí)撤消聯(lián)系,并建立連接。
❤ 第一次握手:建立連接時(shí),客戶(hù)端發(fā)送syn包(syn=j)到服務(wù)器,并進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn);
SYN:同步序列編號(hào)(Synchronize Sequence Numbers)。
❤ 第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶(hù)的SYN(ack=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(seq=k),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);
❤ 第三次握手:客戶(hù)端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1),此包發(fā)送完畢,客戶(hù)端和服務(wù)器進(jìn)入ETABLISHED(TCP連接成功)狀態(tài),完成三次握手。
❤ 完成三次握手,客戶(hù)端與服務(wù)器開(kāi)始傳送數(shù)據(jù)

TCP編程
套接字(Socket)是使用TCP提供了兩臺(tái)計(jì)算機(jī)之間的通信機(jī)制。
客戶(hù)端程序創(chuàng)建一個(gè)套接字,并嘗試連接服務(wù)器的套接字。
當(dāng)連接建立時(shí),服務(wù)器會(huì)創(chuàng)建一個(gè) Socket 對(duì)象??蛻?hù)端和服務(wù)器現(xiàn)在可以通過(guò)對(duì)
Socket 對(duì)象的寫(xiě)入和讀取來(lái)進(jìn)行通信。
► 服務(wù)端:
創(chuàng)建服務(wù)端對(duì)象,監(jiān)聽(tīng)一個(gè)端口
ServerSocket ss = new ServerSocket(100);
獲取客戶(hù)端對(duì)象
Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress();
► 客戶(hù)端:
創(chuàng)建客戶(hù)端socket服務(wù),把ip和端口作為地址傳進(jìn)構(gòu)造函數(shù)
Socket s = new Socket("localhost",100);
UDP的概念和實(shí)現(xiàn)
UDP(User Datagram Protocol):UDP 是用戶(hù)數(shù)據(jù)報(bào)協(xié)議的縮寫(xiě),一個(gè)無(wú)連接的協(xié)議。提供了應(yīng)用程序之間要發(fā)送的數(shù)據(jù)的數(shù)據(jù)包。
用戶(hù)數(shù)據(jù)包協(xié)議(UDP)是網(wǎng)絡(luò)信息傳輸?shù)牧硪环N形式,基于UDP的通信與基于TCP的通信不同,UDP的信息傳遞更快,但不提供可靠的保證。
UDP編程
發(fā)送端:
建立udp服務(wù),發(fā)送端沒(méi)有指定端口,會(huì)自動(dòng)分配一個(gè)端口
DatagramSocket ds = new DatagramSocket();
定義數(shù)據(jù)內(nèi)容,并將數(shù)據(jù)封裝成包
byte[] bt = “hello,udp,我來(lái)了”.getBytes();
把要發(fā)送的數(shù)據(jù)和ip、port封裝到數(shù)據(jù)包里
DatagramPacket db = new
DatagramPacket(bt,bt.length,InetAddress.getByName(“192.168.1.105”),10000);
通過(guò)udp的socket服務(wù)中的功能完成數(shù)據(jù)包的發(fā)送 ds.send(db);
接收端:定義socket服務(wù),監(jiān)聽(tīng)端口
DatagramSocket ds = new DatagramSocket(10000);
預(yù)先定義好一個(gè)數(shù)據(jù)包,用于存儲(chǔ)接收到的數(shù)據(jù)
byte[] bt = new byte[1024];
創(chuàng)建數(shù)據(jù)包對(duì)象,用于接收數(shù)據(jù)
DatagramPacket dp = new
DatagramPacket(bt,bt.length);
使用socket服務(wù)的receive方法將接受到的數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)包中
ds.receive(dp);
通過(guò)數(shù)據(jù)包對(duì)象,獲取數(shù)據(jù)包內(nèi)容
byte[] data = dp.getData();
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
TCP和UDP的區(qū)別
TCP:
1,面向連接的協(xié)議,在socket之間進(jìn)行數(shù)據(jù)傳輸之前必然要建立連接,所以在TCP中需要連接時(shí)間。
2,TCP傳輸數(shù)據(jù)無(wú)大小限制,一旦連接建立起來(lái),雙方的socket就可以按統(tǒng)一的格式傳輸大的數(shù)據(jù)。
3,TCP是一個(gè)可靠的協(xié)議,它確保接收方完全正確地獲取發(fā)送方所發(fā)送的全部數(shù)據(jù)。
UDP:
1,每個(gè)數(shù)據(jù)報(bào)中都給出了完整的地址信息,因此無(wú)需要建立發(fā)送方和接收方的連接。
2,UDP傳輸數(shù)據(jù)時(shí)是有大小限制的,每個(gè)被傳輸?shù)臄?shù)據(jù)報(bào)必須限定在64KB之內(nèi)。
3,UDP是一個(gè)不可靠的協(xié)議,發(fā)送方所發(fā)送的數(shù)據(jù)報(bào)并不一定以相同的次序到達(dá)接收方
TCP和UDP最大的區(qū)別在于是否需要客戶(hù)端與服務(wù)端建立連接后才能進(jìn)行數(shù)據(jù)傳輸。
聊天室
服務(wù)器處理線(xiàn)程
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
public class ServerTask implements Runnable{
private Socket socket;
public ServerTask(Socket socket) {
// TODO 自動(dòng)生成的構(gòu)造函數(shù)存根
this.socket = socket;
}
@Override
public void run() {
// TODO 自動(dòng)生成的方法存根
//建立通信后所執(zhí)行的內(nèi)容
System.out.println("歡迎【"+socket.getRemoteSocketAddress().toString()+"】進(jìn)入聊天室");
//構(gòu)建讀取緩沖
BufferedReader br =null;
//http響應(yīng)寫(xiě)入
PrintWriter pw = null;
try {
//獲取客戶(hù)端輸入的信息 字節(jié)流緩沖成字符流
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg;
while((msg=br.readLine()) != null) {
msg = "【"+socket.getRemoteSocketAddress().toString()+"】說(shuō)"+msg;
//輸出客戶(hù)端信息
System.out.println(msg);
//服務(wù)器接收到客戶(hù)端的消息發(fā)送消息給客戶(hù)端
Scanner scanner = new Scanner(System.in);
System.out.println("請(qǐng)輸入要發(fā)送的信息!");
pw = new PrintWriter(socket.getOutputStream(),true);
pw.println("服務(wù)器說(shuō):"+scanner.nextLine());
pw.flush();
}
}catch (SocketException e) {
// TODO: handle exception
System.out.println(socket.getRemoteSocketAddress().toString()+"退出聊天室!");
}
catch (Exception e) {
// TODO: handle exception
}
}
}
客戶(hù)端處理線(xiàn)程
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
public class ClientTask implements Runnable{
private Socket socket;
public ClientTask(Socket socket) {
// TODO 自動(dòng)生成的構(gòu)造函數(shù)存根
this.socket = socket;
}
@Override
public void run() {
// TODO 自動(dòng)生成的方法存根
try {
while(true) {
Scanner scanner = new Scanner(System.in);
System.out.println("請(qǐng)輸入要發(fā)送的信息");
//消息發(fā)送到服務(wù)器
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
//br.readLine()讀取的消息發(fā)送到服務(wù)器
pw.println(scanner.nextLine());
//讀取服務(wù)器發(fā)送的消息
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
}
}
catch (Exception e) {
// TODO: handle exception
}
}
}
服務(wù)器
import java.net.ServerSocket;
import java.net.Socket;
import com.qingsu.chat.Task.ServerTask;
public class ChatServer {
public static void main(String[] args) {
try {
//創(chuàng)建服務(wù)端對(duì)象 監(jiān)聽(tīng)一個(gè)窗口
ServerSocket serverSocket = new ServerSocket(10622);
System.out.println("服務(wù)器創(chuàng)建成功!端口號(hào)"+10622);
//阻塞 直到有鏈接返回
while(true) {
Socket socket = serverSocket.accept();//獲取客戶(hù)端對(duì)象
//啟動(dòng)一個(gè)線(xiàn)程處理該鏈接
Thread thread = new Thread(new ServerTask(socket));
thread.start();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
客戶(hù)端
import java.net.Socket;
import com.qingsu.chat.Task.ClientTask;
public class ChatClient {
public static void main(String[] args) {
try {
//創(chuàng)建客戶(hù)端socket服務(wù),把ip和端口作為地址傳進(jìn)構(gòu)造函數(shù)
Socket socket = new Socket("127.0.0.1",10622);
//啟動(dòng)客戶(hù)機(jī)線(xiàn)程處理
Thread thread = new Thread(new ClientTask(socket));
thread.start();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
效果

到此這篇關(guān)于Java 全面掌握網(wǎng)絡(luò)編程篇的文章就介紹到這了,更多相關(guān)Java 網(wǎng)絡(luò)編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用ffmpeg和mencoder實(shí)現(xiàn)視頻轉(zhuǎn)碼
這篇文章主要為大家詳細(xì)介紹了Java使用ffmpeg和mencoder實(shí)現(xiàn)視頻轉(zhuǎn)碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
SpringBoot整合新版SpringSecurity完整過(guò)程
Spring Security是保障Spring應(yīng)用程序安全的強(qiáng)大框架,而新版的Spring Security引入了lambda表達(dá)式來(lái)配置,使得安全配置更加簡(jiǎn)潔、優(yōu)雅,本文將介紹如何在Spring Boot項(xiàng)目中整合新版Spring Security,需要的朋友可以參考下2024-02-02
Spring的事件和監(jiān)聽(tīng)器-同步與異步詳解
這篇文章主要介紹了Spring的事件和監(jiān)聽(tīng)器-同步與異步詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Spring Boot中數(shù)據(jù)庫(kù)操作Druid和HikariDataSource的詳細(xì)過(guò)程
這篇文章主要介紹了Spring Boot中數(shù)據(jù)庫(kù)操作Druid和HikariDataSource的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
Spring?Boot實(shí)現(xiàn)JWT?token自動(dòng)續(xù)期的實(shí)現(xiàn)
本文主要介紹了Spring?Boot實(shí)現(xiàn)JWT?token自動(dòng)續(xù)期,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
Mapper層繼承BaseMapper<T>需要引入的pom依賴(lài)方式
這篇文章主要介紹了Mapper層繼承BaseMapper<T>需要引入的pom依賴(lài)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01

