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

客戶機服務器模式(Client/Server)
●為了實現(xiàn)兩臺計算機的通信,必須要用一個網(wǎng)絡線路連接兩臺計算機。
● 服務器(Server)是指提供信息的計算機或程序
●客戶機(Client)是指請求信息的計算機或程序
●網(wǎng)絡用于連接服務器與客戶機,實現(xiàn)兩者相互通信。

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

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

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

