日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【网络编程】Socket网络编程基础

發(fā)布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【网络编程】Socket网络编程基础 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 網(wǎng)絡(luò)編程概述
    • Socket與TCP UDP
    • Socket TCP演示
    • 報文段
    • 協(xié)議
    • Mac地址
    • IP、端口、遠(yuǎn)程服務(wù)器
      • IPv4
      • IPv6
      • 端口
      • 遠(yuǎn)程服務(wù)器

網(wǎng)絡(luò)編程概述

什么是網(wǎng)絡(luò)編程

網(wǎng)絡(luò)編程從大的方面說就是對信息的發(fā)送到接收

通過操作相應(yīng)Api調(diào)度計算機(jī)硬件資源,并利用傳輸管道(網(wǎng)線)進(jìn)行數(shù)據(jù)交換的過程

更為具體的涉及:網(wǎng)絡(luò)模型、套接字、數(shù)據(jù)包

網(wǎng)絡(luò)模型 – 對應(yīng)關(guān)系

具體細(xì)節(jié)看一看我的 專欄《計算機(jī)網(wǎng)絡(luò)》

Socket與TCP UDP

關(guān)于Socket
簡單來說是IP地址與端口的結(jié)合協(xié)議(RFC793)

一種地址與端口的結(jié)合描述協(xié)議

TCP/IP協(xié)議的相關(guān)API的總稱;是網(wǎng)絡(luò)Api的集合實(shí)現(xiàn)

涵蓋了:Stream Socket/Datagram Socket

Socket的作用與組成
在網(wǎng)絡(luò)傳輸中用于唯一標(biāo)示兩個端點(diǎn)之間的鏈接

端點(diǎn):包括(IP+Port)

4個要素:客戶端地址、客戶端端口、服務(wù)器地址、服務(wù)器端口

Socket 傳輸原理

Socket – TCP
TCP是面向連接的通信協(xié)議

通過三次握手建立連接,通訊完成時要拆除連接

由于TCP是面向連接的所以只能用于端到端的通訊

Socket – UDP
UDP是面向無連接的通訊協(xié)議

UDP數(shù)據(jù)包括目的端口號和源端口號信息

由于通訊不需要連接,所以可以實(shí)現(xiàn)廣播發(fā)送,并不局限于端到端

TCP 傳輸

UDP傳輸

Client-Server Application

TCP/IP協(xié)議中,兩個進(jìn)程間通信的主要模式為:CS模型

主要目的:協(xié)同網(wǎng)絡(luò)中的計算機(jī)資源、服務(wù)模式、進(jìn)程間數(shù)據(jù)共享

常見的:FTP、SMTP、HTTP

Socket TCP演示

構(gòu)建TCP客戶端、服務(wù)端
客戶端發(fā)送數(shù)據(jù)
服務(wù)器讀取數(shù)據(jù)并打印


創(chuàng)建一個默認(rèn)文件夾

服務(wù)器端
Server.java

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(2000); //服務(wù)器準(zhǔn)備就緒System.out.println("服務(wù)器準(zhǔn)備就緒!");System.out.println("服務(wù)器信息:"+server.getInetAddress()+" p: "+server.getLocalPort());//等待客戶端連接while (true){Socket client = server.accept(); //監(jiān)聽連接到一個客戶端//客戶端構(gòu)建異步線程ClientHandler clientHandler = new ClientHandler(client);//啟動線程clientHandler.start();}}//客戶端消息處理private static class ClientHandler extends Thread{private Socket socket;private boolean flag = true;ClientHandler(Socket socket){this.socket = socket;}@Overridepublic void run() {super.run();System.out.println("新客戶端連接:"+ socket.getInetAddress() + " p"+socket.getPort()); //客戶端的try {//得到打印流,用于數(shù)據(jù)輸出;服務(wù)器回送數(shù)據(jù)使用PrintStream socketOutput = new PrintStream(socket.getOutputStream());//得到輸入流,用于接收數(shù)據(jù)BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));do{//客戶端拿出一條數(shù)據(jù)String str = socketInput.readLine();if("bye".equalsIgnoreCase(str)){flag = false;//回送socketOutput.println("bye");}else {//打印到屏幕 并回送數(shù)據(jù)長度System.out.println(str);socketOutput.println("回送:"+str.length());}}while (flag);//打印到屏幕。 并回送數(shù)據(jù)長度socketInput.close();socketOutput.close();} catch (IOException e) {System.out.println("連接異常斷開");e.printStackTrace();} finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}System.out.println("客戶端已退出" + socket.getInetAddress() +" port:"+socket.getPort());}} }

Client.java

import java.io.*; import java.net.*;public class Client {public static void main(String[] args) throws IOException {Socket socket = new Socket();//超時時間socket.setSoTimeout(3000);//連接本地 端口號2000 超時時間是3000mssocket.connect(new InetSocketAddress(Inet4Address.getLocalHost(),2000),3000);// public void connect(SocketAddress endpoint, int timeout)//socket地址 = ip + 端口號System.out.println("已發(fā)起服務(wù)器連接,并進(jìn)入后續(xù)流程~~~");System.out.println("客戶端信息:"+socket.getLocalAddress()+" port:"+socket.getLocalPort());System.out.println("服務(wù)器信息"+socket.getInetAddress()+" port:"+socket.getPort());try {todo(socket); //發(fā)送接收數(shù)據(jù)}catch (Exception e){System.out.println("異常退出");}socket.close();System.out.println("客戶端已退出");}private static void todo(Socket client) throws IOException {InputStream in = System.in; //鍵盤輸入流BufferedReader input = new BufferedReader(new InputStreamReader(in));//得到Socket輸出流 并轉(zhuǎn)換為打印流OutputStream outputStream = client.getOutputStream();PrintStream socketPrintStream = new PrintStream(outputStream);//得到Socket輸入流 并轉(zhuǎn)換為BufferedReaderInputStream inputStream = client.getInputStream();BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream));boolean flag = true;do{//讀取一行String string = input.readLine();//發(fā)送到服務(wù)器socketPrintStream.println(string);//從服務(wù)器讀取一行String echo = socketBufferedReader.readLine();if ("bye".equalsIgnoreCase(echo)){flag = false;}else {System.out.println(echo);}}while (flag);//釋放資源socketBufferedReader.close();socketPrintStream.close();} }

啟動服務(wù)器端(服務(wù)器端窗口)

啟動客戶端(客戶端窗口)

服務(wù)器端窗口 變化:

在客戶端窗口 輸入“Hello”

服務(wù)器端變化

輸入bye

重新運(yùn)行客戶端 服務(wù)器端又會接入新的連接


按過程分析:
最初的時候,準(zhǔn)備服務(wù)器

ServerSocket server = new ServerSocket(2000); //服務(wù)器準(zhǔn)備就緒

關(guān)于ServerSocket類 查閱API

再看看它的構(gòu)造方法:

加上端口之后 我們的服務(wù)器套接字就完成了


System.out.println("服務(wù)器準(zhǔn)備就緒!");System.out.println("服務(wù)器信息:"+server.getInetAddress()+" p: "+server.getLocalPort());

接著 我們打印了一些相關(guān)的信息 來探究這個過程中發(fā)生了什么 我們需要關(guān)注ServerSocket類 的方法

當(dāng)然這一步并不是必要的,這里只是演示需要
重要的是 服務(wù)器套接字完成之后,需要等待客戶端連接 這里就需要去監(jiān)聽來自客戶端連接的消息了 就是下面的內(nèi)容


Socket client = server.accept(); //監(jiān)聽連接到一個客戶端//客戶端構(gòu)建異步線程


它的返回值 是Socket (客戶端套接字)
我們來看看 Socket類的情況


下面轉(zhuǎn)入客戶端的情況

Socket socket = new Socket();//超時時間socket.setSoTimeout(3000);

首先建立起Socket的實(shí)現(xiàn)類 socket
此時的socket類 還沒有相關(guān)的配置信息
我們?yōu)樗O(shè)置去連接客戶端的超時時間 單位是毫秒

下面配置連接的情況

//連接本地 端口號2000 超時時間是3000mssocket.connect(new InetSocketAddress(Inet4Address.getLocalHost(),2000),3000);// public void connect(SocketAddress endpoint, int timeout)


關(guān)于SocketAddress

它是一個抽象類
我們來看它的直接子類 也就是我們new出來的東西:

關(guān)注它的構(gòu)造方法:

我們通過它們 實(shí)現(xiàn)與服務(wù)器的連接


//socket地址 = ip + 端口號System.out.println("已發(fā)起服務(wù)器連接,并進(jìn)入后續(xù)流程~~~");System.out.println("客戶端信息:"+socket.getLocalAddress()+" port:"+socket.getLocalPort());System.out.println("服務(wù)器信息"+socket.getInetAddress()+" port:"+socket.getPort());

下面我們打印 演示的信息



演示中 我們在控制臺輸入字符串,非bye的話 服務(wù)器接收并且進(jìn)行打印
我們看看我們這邊的處理方式

InputStream in = System.in; //鍵盤輸入流BufferedReader input = new BufferedReader(new InputStreamReader(in));

鍵盤輸入流 轉(zhuǎn)成緩沖流

//得到Socket輸出流 并轉(zhuǎn)換為打印流OutputStream outputStream = client.getOutputStream();PrintStream socketPrintStream = new PrintStream(outputStream);


得到Socket輸出流 并轉(zhuǎn)換為打印流 打印輸出流的流向和該套接字一樣

//讀取一行String string = input.readLine();//發(fā)送到服務(wù)器socketPrintStream.println(string);

接下來讀取自己在控制臺輸入的字符串
發(fā)送到服務(wù)器


服務(wù)器接收客戶端的消息

//得到打印流,用于數(shù)據(jù)輸出;服務(wù)器回送數(shù)據(jù)使用PrintStream socketOutput = new PrintStream(socket.getOutputStream());//得到輸入流,用于接收數(shù)據(jù)BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));

得到打印流 然后轉(zhuǎn)換成緩沖流
接著讀取消息

//客戶端拿出一條數(shù)據(jù)String str = socketInput.readLine();if("bye".equalsIgnoreCase(str)){flag = false;//回送socketOutput.println("bye");}else {//打印到屏幕 并回送數(shù)據(jù)長度System.out.println(str);socketOutput.println("回送:"+str.length());}

我們打印到控制臺 然后可以給客戶端回復(fù)消息
剩下的就基本上沒什么好解釋的了。

報文段

報文段是指TCP/IP協(xié)議網(wǎng)絡(luò)傳輸過程中,起著路由導(dǎo)航作用

用以查詢各個網(wǎng)絡(luò)路由網(wǎng)段、IP地址、交換協(xié)議等IP數(shù)據(jù)包

報文段充當(dāng)整個TCP/IP協(xié)議數(shù)據(jù)包的導(dǎo)航路由功能

報文在傳輸過程中會不斷地封裝成分組、包、幀來傳輸

封裝方式就是添加一些控制信息組成的首部,即報文頭

協(xié)議

傳輸協(xié)議
協(xié)議顧名思義,一種規(guī)定,約束

約定大于配置,在網(wǎng)絡(luò)傳輸中依然適用;網(wǎng)絡(luò)的傳輸流程是健壯的穩(wěn)定的,得益于基礎(chǔ)的協(xié)議構(gòu)成

簡單來說:A->B的傳輸數(shù)據(jù),B能識別,反之B->A的傳輸數(shù)據(jù)A也能識別,這就是協(xié)議

Mac地址

Media Access Control或者M(jìn)edium Access Control

意譯為媒體訪問控制,或稱為物理地址、硬件地址

用來定義網(wǎng)絡(luò)設(shè)備的位置

形如:44-45-53-54-00-00;與身份證類似

IP、端口、遠(yuǎn)程服務(wù)器

IPv4

IP互聯(lián)網(wǎng)協(xié)議地址(英語:Internet Protocol Address,又譯為網(wǎng)際協(xié)議地址),縮寫為IP地址(英語:IP Address)

是分配給網(wǎng)絡(luò)上使用網(wǎng)際協(xié)議(英語:Internet Protocol,IP)的設(shè)備的數(shù)字標(biāo)簽

常見的IP地址分為IPv4與IPv6兩大類

IP地址由32位二進(jìn)制數(shù)組成,常以XXX.XXX.XXX.XXX形式表現(xiàn),每組XXX代表小于或等于255的10進(jìn)制數(shù) 如:208.80.152.2

如果主機(jī)號是全1,那么這個地址為直接廣播地址

IP地址“255.255.255.255”為受限廣播地址

IPv6

總共有128位長,IPV6地址的表達(dá)形式,一般采用32個十六進(jìn)制數(shù)。
也可以想象為1632個

由兩個邏輯部分組成:一個64位的網(wǎng)絡(luò)前綴和一個64位的主機(jī)地址,主機(jī)地址通常根據(jù)物理地址自動生成,叫做EUI-64(或者64-位擴(kuò)展唯一標(biāo)識) 比如:2001:0db8:85a3:0000:1319:8a2e:0370:7344

IPv4轉(zhuǎn)換為IPv6一定可行,IPv6轉(zhuǎn)換為IPv4不一定可行

端口

如果把IP地址比作一間房子,端口就是出入這間房子的門或者窗戶

在不同門窗戶后有不同的人,房子中的用戶與外界交流的出口

外界鴿子(信息)飛到不同窗戶也就是給不同的人傳遞信息

0到1023號端口以及1024到49151號端口都是特殊端口

特殊端口號

計算機(jī)之間依照互聯(lián)網(wǎng)傳輸層TCP/IP協(xié)議的協(xié)議通信,不同的協(xié)議都對應(yīng)不同的端口

49152到65535號端口屬于“動態(tài)端口”范圍,沒有端口可以被正式地注冊占用

傳輸層次

這里僅僅是簡單復(fù)習(xí)
關(guān)于報文的情況 打算寫一篇博文 全面講解這些東西

遠(yuǎn)程服務(wù)器

局域網(wǎng):一般而言,家里的環(huán)境以及公司相互電腦之間環(huán)境都屬于局域網(wǎng)

我與你們的電腦之間屬于互聯(lián)網(wǎng),而非局域網(wǎng)

默認(rèn)的:我的電腦無法直接鏈接到你們的電腦

Web請求流程

總結(jié)

以上是生活随笔為你收集整理的【网络编程】Socket网络编程基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。