一、 網(wǎng)絡(luò)編程
1.1 什么是網(wǎng)絡(luò)編程
解釋:
在網(wǎng)絡(luò)通信協(xié)議下,不同計(jì)算機(jī)上運(yùn)行的程序,進(jìn)行的數(shù)據(jù)傳輸
應(yīng)用場(chǎng)景:即時(shí)通信、網(wǎng)游對(duì)戰(zhàn)、金融證券、國(guó)際貿(mào)易、郵件、等等不管是什么場(chǎng)景,都是計(jì)算機(jī)跟計(jì)算機(jī)之間通過(guò)網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)傳輸
- Java中可以使用
java.net
包下的技術(shù)輕松開(kāi)發(fā)出常見(jiàn)的網(wǎng)絡(luò)應(yīng)用程序
1.2 常見(jiàn)的軟件架構(gòu):
-
cs —>
Client/Server
-
bs:
Browser/Server
BS架構(gòu)的優(yōu)缺點(diǎn):
- 不需要開(kāi)發(fā)客戶端,只需要頁(yè)面+服務(wù)端
- 用戶不需要下載,打開(kāi)瀏覽器就能使用
- 如果應(yīng)用過(guò)大,用戶體驗(yàn)受到影響
可能會(huì)導(dǎo)致游戲加載不出來(lái)
CS架構(gòu)的優(yōu)缺點(diǎn):
- 畫(huà)面可以做的非常精美,用戶體驗(yàn)好
- 需要開(kāi)發(fā)客戶端,也需要開(kāi)發(fā)服務(wù)端
- 用戶需要下載和更新的時(shí)候太麻煩
CS:適合定制專業(yè)化的辦公類軟件如: IDEA、網(wǎng)游
BS:適合移動(dòng)互聯(lián)網(wǎng)應(yīng)用,可以在任何地方隨時(shí)訪問(wèn)的系統(tǒng)
1.3 網(wǎng)絡(luò)編程的三要素
IP
- 設(shè)備在網(wǎng)絡(luò)中的地址,是唯一的標(biāo)識(shí)。
端口號(hào)
- 應(yīng)用程序在設(shè)備中唯一的標(biāo)識(shí)。
協(xié)議
- 數(shù)據(jù)在網(wǎng)絡(luò)中傳輸?shù)囊?guī)則,常見(jiàn)的協(xié)議有UDP、TCP、http、https、ftp。
1.4 IP
全稱:Internet Protocol,是互聯(lián)網(wǎng)協(xié)議地址,也稱IP地址是分配給上網(wǎng)設(shè)備的數(shù)字標(biāo)簽
”說(shuō)人話:“上網(wǎng)設(shè)備
在網(wǎng)絡(luò)中的地址,是唯一
的
IPv4
全稱:Internet Protocolversion 4,互聯(lián)網(wǎng)通信協(xié)議第四版。采用32位地址長(zhǎng)度,分成4組
由于太少I(mǎi)P值,現(xiàn)在又出現(xiàn)了IPv6
IPv6
- 全稱:Internet Protocol version6 ,互聯(lián)網(wǎng)通信協(xié)議第六版
- 由于互聯(lián)網(wǎng)的蓬勃發(fā)展,IP地址的需求量愈來(lái)愈大,而IPv4的模式下IP的總數(shù)是有限的,采用128位地址長(zhǎng)度,分成8組
![]()
2.IPv4有什么特點(diǎn)目前的主流方案最多只有2^32次方個(gè)ip,目前已經(jīng)用完了
3.IPv6有什么特點(diǎn)為了解決IPv4不夠用而出現(xiàn)的最多有2^128次方個(gè)ip可以為地球上的每一粒沙子都設(shè)定ip
lPv4的地址分類形式
- 公網(wǎng)地址(萬(wàn)維網(wǎng)使用)和私有地址(局域網(wǎng)使用)。
-
192.168.
開(kāi)頭的就是私有址址
,范圍即為192.168.0.0–192.168.255.255,
專門(mén)為組織機(jī)構(gòu)內(nèi)部使用,以此節(jié)省IP
特殊IP地址
127.0.0.1,也可以是localhost:是回送地址也稱本地回環(huán)地址,也稱本機(jī)IP,永遠(yuǎn)只會(huì)尋找當(dāng)前所在本機(jī)。
常用的CMD命令ipconfig
: 查看本機(jī)IP地址ping
:檢查網(wǎng)絡(luò)是否連通
1.4.1 InetAddress用法
用法 | 使用說(shuō)明 |
---|---|
static InetAddress getByName(String host) | 確定主機(jī)名稱的IP地址。主機(jī)名稱可以是機(jī)器名稱,也可以是IP地址 |
String getHostName() | 獲取此IP地址的主機(jī)名 |
String getHostAddress() | 返回文本顯示中的IP地址字符串 |
package Mysocketnet.MyInetAddressDom;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Dom1 {
public static void main(String[] args) throws UnknownHostException {
//獲取到InetAddress對(duì)象
InetAddress address = InetAddress.getByName("lzqxiaojiaoqi");
System.out.println(address);
//獲取電腦名字
String hostName = address.getHostName();
System.out.println(hostName);//lzqxiaojiaoqi
//獲取IP地址
String ip = address.getHostAddress();
System.out.println(ip);//10.200.27.49
}
}
1.5 端口號(hào)
應(yīng)用程序在設(shè)備中唯一的標(biāo)識(shí)。
端口號(hào):
- 由兩個(gè)字節(jié)表示的整數(shù),取值范圍:0~ 65535
- 其中0~1023之間的端口號(hào)用于一些知名的網(wǎng)絡(luò)服務(wù)或者應(yīng)用
- 我們自己使用1024以上的端口號(hào)就可以了
注意:一個(gè)端口號(hào)只能被一個(gè)應(yīng)用程序使用
1.6 協(xié)議
TCP/IP 模型:
1.6.1 UDP協(xié)議
特點(diǎn):
- 用戶數(shù)據(jù)報(bào)協(xié)議(User Datagram Protocol)
- UDP是面向無(wú)連接通信協(xié)議。
速度快,有大小限制一次最多發(fā)送64K,數(shù)據(jù)不安全,易丟失數(shù)據(jù)
由于會(huì)缺失數(shù)據(jù),傳輸快,主要應(yīng)用于語(yǔ)音通話、看視頻、網(wǎng)絡(luò)會(huì)議等等
UDP通信程序(發(fā)送數(shù)據(jù)):
-
找快遞公司 ---->
創(chuàng)建發(fā)送端的DatagramSocket對(duì)象
-
打包禮物 ---->
數(shù)據(jù)打包(DatagramPacket)
-
快遞公司發(fā)送包裹 ---->
發(fā)送數(shù)據(jù)
-
付錢(qián)走人 ---->
釋放資源
package Mysocketnet.MyUDP;
import java.io.IOException;
import java.net.*;
public class SendMessageDom {
public static void main(String[] args) throws IOException {
//創(chuàng)建DatagramSocket(快遞公司)
DatagramSocket ds = new DatagramSocket();
//打包數(shù)據(jù)(DatagramPacket)
//首先創(chuàng)建需要傳輸?shù)臄?shù)據(jù),變成byte[]傳輸
String str = "Hello World !!";
byte[] bytes = str.getBytes();
int port = 10086;
InetAddress address = InetAddress.getByName("127.0.0.1");
//參數(shù):1. 需要傳輸?shù)臄?shù)據(jù)byte[],2.截取的長(zhǎng)度,3. id值,4. 端口
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
//發(fā)送數(shù)據(jù)(包裹)
ds.send(packet);
//清理資源
ds.close();
}
}
UDP通信程序(接收數(shù)據(jù)):
- 找快遞公司 ----->
創(chuàng)建接收端的DatagramSocket對(duì)象
- 接收箱子 ----->
接收打包好的數(shù)據(jù)
- 從箱子里面獲取禮物 ----->
解析數(shù)據(jù)包
- 簽收走人 ----->
釋放資源
package Mysocketnet.MyUDP;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class ReceiveMessageDom {
public static void main(String[] args) throws IOException {
//創(chuàng)建DatagramSocket
//注意:要傳輸端口號(hào)碼,而且傳輸?shù)亩丝谔?hào)碼,要與傳輸端一致,要不然接受不到數(shù)據(jù)
DatagramSocket ds = new DatagramSocket(10086);
//接收數(shù)據(jù),創(chuàng)建DatagramPacket空的數(shù)組對(duì)象接受傳來(lái)的數(shù)據(jù)
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
//把數(shù)據(jù)拿出來(lái)
InetAddress address = dp.getAddress();
byte[] data = dp.getData();
int length = dp.getLength();
int port = dp.getPort();
System.out.println("是"+address+"該IP通過(guò)"+port+"端口號(hào),發(fā)過(guò)來(lái)的"+new String(data,0,length));
//關(guān)閉窗口
ds.close();
}
}
dp.receive:
需要等到接收到數(shù)據(jù)過(guò)后才進(jìn)行下面代碼的實(shí)現(xiàn)
練習(xí):
發(fā)送:
package Mysocketnet.MyUDP.Exercise;
import javax.sound.sampled.Port;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
//創(chuàng)建一個(gè)聊天室
//輸入是鍵盤(pán)輸入,直到輸入的是886的時(shí)候才停止。
public class Send {
public static void main(String[] args) throws IOException {
//創(chuàng)建DatagramSocket(快遞公司)
DatagramSocket ds = new DatagramSocket();
//打包數(shù)據(jù)
//首先通過(guò)鍵盤(pán)輸入數(shù)據(jù),在集訓(xùn)打包
Scanner sc = new Scanner(System.in);
InetAddress address = InetAddress.getByName("127.0.0.1");
//端口號(hào)
int port = 10086;
while (true){
//鍵盤(pán)錄入數(shù)據(jù),請(qǐng)將數(shù)據(jù)傳輸為byte[]類型
System.out.println("請(qǐng)輸入數(shù)據(jù)");
String str = sc.nextLine();
byte[] bytes = str.getBytes();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
//發(fā)送
ds.send(dp);
System.out.println("發(fā)送成功");
if (str.equals("886")){
System.out.println("聊天結(jié)束");
break;
}
}
//關(guān)閉
ds.close();
}
}
接收:
package Mysocketnet.MyUDP.Exercise;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//創(chuàng)建一個(gè)聊天室
//接收數(shù)據(jù),一直接收數(shù)據(jù),采用死循環(huán)
public class Receive {
public static void main(String[] args) throws IOException {
//創(chuàng)建DatagramSocket(接收數(shù)據(jù)的端口號(hào))
DatagramSocket ds = new DatagramSocket(10086);
//一直接收數(shù)據(jù)
//創(chuàng)建空包裹來(lái)接受數(shù)據(jù)
byte[] bytes = new byte[1024];
while (true){
//創(chuàng)建DatagramPacket
DatagramPacket dp = new DatagramPacket(bytes, 0, bytes.length);
//接收數(shù)據(jù)
ds.receive(dp);
System.out.println(new String(dp.getData())+"-------"+dp.getAddress());
}
}
}
1.6.1.1 UDP的三種通信方式
-
單播:
單個(gè)發(fā)送數(shù)據(jù)
以前的代碼就是單播 -
組播:
發(fā)送一小部分?jǐn)?shù)據(jù)
組播地址: 224.0.0.0 ~ 239.255.255.255
其中224.0.0.0 ~ 224.0.0.255 為預(yù)留的組播地址 -
廣播:
全部數(shù)據(jù)發(fā)送
廣播地址: 255.255.255.255
組播與上方代碼不相同的地方是:
//創(chuàng)建MulticastSocket對(duì)象
MulticastSocket ms = new MulticastSocket()
//接收的地址改為
InetAddress address = InetAddress.getByName("224.0.0.1");
1.6.2 TCP協(xié)議
- 傳輸控制協(xié)議TCP(Transmission Control Protocol)
- TCP協(xié)議是面向連接的通信協(xié)議。
速度慢,沒(méi)有大小限制,數(shù)據(jù)安全
由于傳輸數(shù)據(jù)相對(duì)較慢,但是傳輸時(shí)不會(huì)丟失數(shù)據(jù),主要應(yīng)用于:文字聊天,發(fā)送郵件
TCP通信程序
- TCP通信協(xié)議是一種可靠的網(wǎng)絡(luò)協(xié)議,它在通信的兩端各建立一個(gè)Socket對(duì)象
通信之前要保證連接已經(jīng)建立
- 通過(guò)Socket產(chǎn)生
IO流
來(lái)進(jìn)行網(wǎng)絡(luò)通信![]()
客戶端(Socket):
- 創(chuàng)建客戶端的Socket對(duì)象(Socket)與指定服務(wù)端連接
Socket(string host, int port)
- 獲取輸出流,寫(xiě)數(shù)據(jù)
Outputstream getOutputstream()
- 釋放資源
void close()
package Mysocketnet.MyTCP;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
//用TCP來(lái)創(chuàng)建監(jiān)聽(tīng)窗口(發(fā)送數(shù)據(jù))
public class client {
public static void main(String[] args) throws IOException {
//創(chuàng)建Socket對(duì)象
Socket socket = new Socket("127.0.0.1", 10086);
//創(chuàng)建連接通道
OutputStream os = socket.getOutputStream();
os.write("男孩女孩".getBytes());
//清理資源
os.close();
socket.close();
}
}
服務(wù)端:
- . 創(chuàng)建服務(wù)器端的Socket對(duì)象(ServerSocket)
ServerSocket(int port)
- 監(jiān)聽(tīng)客戶端連接,返回一個(gè)Socket對(duì)象
Socket accept()
3 . 獲取輸入流,讀數(shù)據(jù),并把數(shù)據(jù)顯示在控制臺(tái)Inputstream getInputstream()
- 釋放資源
void close()
package Mysocketnet.MyTCP;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//利用TCP來(lái)創(chuàng)建服務(wù)器端口(接收數(shù)據(jù))
public class service {
public static void main(String[] args) throws IOException {
//創(chuàng)建Socket對(duì)象
ServerSocket ss = new ServerSocket(10086);
//創(chuàng)建接收數(shù)據(jù)
Socket accept = ss.accept();
//連接通道獲取其傳輸?shù)闹?/span>
// InputStream is = accept.getInputStream();
//因?yàn)樵谶@里創(chuàng)建的是字節(jié)流是一個(gè)字節(jié)一個(gè)字節(jié)的讀取就會(huì)導(dǎo)致亂碼
//所有通過(guò)這里的轉(zhuǎn)換流轉(zhuǎn)成字符流
BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
int b;
while ((b = br.read()) != -1){
System.out.println((char) b);
}
//清理資源
accept.close();
ss.close();
}
}
注意事項(xiàng):
- 我們?cè)诶?code>客戶端傳輸數(shù)據(jù)的時(shí)候必須要保證連接正常,要么就會(huì)報(bào)錯(cuò)
- 我們?cè)趧?chuàng)建的服務(wù)端,在讀取數(shù)據(jù)的時(shí)候,可以利用轉(zhuǎn)換流將
字節(jié)流
轉(zhuǎn)換為字符流
,不僅提高了效率
,還防止了亂碼
1.6.2.1 TCP底層原理
三次握手:
確保鏈接
四次揮手:
確保連接斷開(kāi),并且使得數(shù)據(jù)處理完全
個(gè)人理解:(可能不恰當(dāng),適當(dāng)理解)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-450119.html
相當(dāng)于就是先跟服務(wù)器說(shuō)我要執(zhí)行某個(gè)任務(wù)在服務(wù)器上,然后服務(wù)器同意后給與消息返回,但是要等到服務(wù)器手上的事情做完才能夠發(fā)送同意消息,等到客戶端拿到消息的時(shí)候,以為不成功,騙他的,再次向服務(wù)器確認(rèn)信息后才安心的去執(zhí)行任務(wù)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-450119.html
到了這里,關(guān)于Java基礎(chǔ)學(xué)習(xí)(17)網(wǎng)絡(luò)編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!