SQL常用查詢
網路程式設計
目錄網路基礎知識:
IP地址:
- 唯一標識主機
- 對於IPV4來說有4個位元組,一個位元組範圍為0~255
- ip地址的組成192.168.1.110 網路地址+主機地址
- IPV6是由於IPV4地址不夠用,用於替代IPV4的下一代IP協議
域名和埠號:
- 域名方便記憶(IP地址)
- IP地址找到主機,埠號找到主機裡的不同服務
- 在開發中,不要使用0-1024的埠,這些埠一般名花有主了
網路協議(為了讓兩臺主機能夠資料傳輸):
中國人跟中國人說話,聽得懂,
你用中國話跟外國人說話,外國人聽不懂,語言就是一個協議
而計算機和計算機之間,資料的組織形式,也就是一種協議
TCP和UDP:
TCP:傳輸控制協議
雙向奔赴的愛情,找一個值得的人慢,但是可靠,可以付出很多感情(大量資料)
-
傳輸前必須三次握手,確認可以進行大量資料傳輸,可靠
-
通訊的兩個應用程序:客戶端,服務端
-
傳輸完畢後,需要釋放已建立的連線,效率低
三次握手:
客戶端 傳送訊息x給伺服器,伺服器迴應訊息x+1和y給客戶端,客戶到收到x+1確定伺服器可以連線到,再發送y+1給伺服器,伺服器收到,確定客戶端收到了自己的訊息,正常開始傳輸
UDP:使用者資料協議
不認真對待的愛情很容易找到,快,但是不可靠,不能付出太多感情(不適合傳輸大量資料)
- 不需要建立連線,不可靠
- 不適合傳輸大量資料
- 傳送接受不需要關閉連線,速度快
InetAddress:
用處:獲取本地的ip地址和主機名,通過域名獲取其他主機的ip地址和主機名
public static void main(String[] args) throws UnknownHostException { // 1.獲取本機的InetAdddress物件 InetAddress localHost =InetAddress.getLocalHost(); System.out.println(localHost); // 2.根據主機名獲取InetAdddre物件 InetAddress byName = InetAddress.getByName("Producer-2021XC"); System.out.println(byName); // 3.根據域名返回InetAdddre物件 InetAddress byName1 = InetAddress.getByName("www.baidu.com"); System.out.println(byName1); // 4.通過物件獲取地址 String hostAddress = byName1.getHostAddress(); System.out.println(hostAddress); // 5.通過物件獲取主機名/或者域名 String hostName = byName.getHostName(); System.out.println(hostName); }
Socket:
- 套接字
- 通訊兩端都有Socket,是通訊的端點
- 網路通訊其實就是Socket的通訊
- Socket使網路連線成一個流,資料在兩個Socket間通過Io傳輸
- 底層使用的是TCP/IP協議
TCP位元組流程式設計:
基礎流程:
- 客戶端和服務端是靠socket的資料通道進行傳輸的
- 啟動順序:必須先啟動服務端,再開啟客戶端,服務端要先監聽,而且客戶端要是開啟,去獲取連線也獲取不到
- 服務端:獲取監聽 》獲取socket 》獲取輸入流
- 客戶端:獲取連線(ip地址,埠號)》 獲取輸入流
- 每傳送完一次資訊要記得,設定結束標誌
位元組流的傳輸:
服務端:
public static void main(String[] args) throws IOException {
// 思路:
// 1.首先拿到埠號為9999的監聽
// 要求沒用其他服務監聽9999
// 這個serverSocket可以返回多個accept,多個客戶端來連線伺服器併發
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("===開始監聽===");
// 2.接收連線,如果沒用客戶端連線上這個埠就會阻塞
Socket accept = serverSocket.accept();
System.out.println("成功獲取客戶端連線");
// 3.通過輸入流接收客戶端訊息
InputStream IS = accept.getInputStream();
System.out.println(IS.getClass());
byte[]buf=new byte[1024];
int readlend=0;
while ((readlend=IS.read(buf))!=-1){
System.out.println(new String(buf,0,readlend));
}
System.out.println("服務端關閉");
IS.close();
accept.close();
serverSocket.close();
}
客戶端
public static void main(String[] args) throws IOException {
// 思路:
// 1.連線伺服器(ip,埠)
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
// 2.連線後,生成Socket
OutputStream OS = socket.getOutputStream();
// 3.通過輸出流,寫入資料到資料管道
OS.write("hello,server".getBytes());
System.out.println("客戶端關閉");
OS.close();
socket.close();
}
回傳:
當客戶端傳送後,要接收服務端的回傳資訊,服務端收到後,要向客戶端傳送訊息
注意點:傳完(接收)後要設定接收接收標記,不然socket會不知道你是否完成,造成堵塞
accept.shutdownInput();
accept.shutdownOutput();
服務端
public static void main(String[] args) throws IOException {
// 服務端只需要寫當前服務的埠號就行了
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服務端開啟");
Socket accept = serverSocket.accept();
System.out.println("獲取接收資訊:");
InputStream IS = accept.getInputStream();
OutputStream OS = accept.getOutputStream();
byte buf[]=new byte[1024];
int readline=0;
System.out.println("接收到客戶端資訊");
while ((readline=IS.read(buf))!=-1){
System.out.println(new String(buf,0,readline));
}
// 設定結束標記
accept.shutdownInput();
System.out.println("向客戶端回傳資訊");
OS.write("hello,client".getBytes());
IS.close();
OS.close();
accept.close();
serverSocket.close();
}
}
客戶端
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
OutputStream OS = socket.getOutputStream();
InputStream IS = socket.getInputStream();
System.out.println("向服務端傳送資訊:");
OS.write("hello,server".getBytes());
// 設定結束標記
socket.shutdownOutput();
byte buf[]=new byte[1024];
int readline=0;
System.out.println("接收服務端資訊");
while ((readline=IS.read(buf))!=-1){
System.out.println(new String(buf,0,readline));
}
IS.close();
OS.close();
socket.close();
}
用字元流傳遞字串
轉換流轉成字元流(字元流寫入後要flush,不然資料進不到管道)其他一樣
涉及快取必須flush
下載檔案/上傳檔案:
思路:
客戶端:先讀取本地資源,再用socket的輸出流,輸出到服務端
服務端:先讀取socket輸入流,再輸出到本地磁碟
注意點:
當客戶端連線到服務端後,實際上客戶端也是通過一個埠來跟伺服器連線的,並且不是跟服務端相同的埠,這個埠是由TCP/IP隨機分配,不確定
輸入流或者輸出流不能在shutdownOutput或者另外一個前先退出,不然會造成socket close異常,也就是你的流不能在標記前退出,可能訊息沒完
netstat:
-
netstat - an檢視主機網路情況
-
netstat - an | more分頁檢視
-
Listening表示那個埠在監聽
UDP網路程式設計:
基礎流程:
- 特點就是UDP不在乎對方是否收到
- 通過DategramSocket和DategramPacket(資料包)實現了UDP協議網路程式
- 沒有明確的服務端和客戶端,只有傳送端和接收端,所以是通過DategramSocket接收和傳送
- 通過DategramPacket封裝資料,既然封裝了資料,就肯定有拆包的過程
A端
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(8888);
while (true){
Scanner scanner = new Scanner(System.in);
// 傳送包併發送資料
System.out.println("傳送訊息:");
String content = scanner.next();
if (content.equals("退出")){
break;
}
DatagramPacket packetSE = new DatagramPacket(content.getBytes(StandardCharsets.UTF_8), content.length(), InetAddress.getLocalHost(), 9999);
datagramSocket.send(packetSE);
//接收包並輸出訊息
byte []byteRE=new byte[1024];
DatagramPacket packetRE = new DatagramPacket(byteRE,byteRE.length);
datagramSocket.receive(packetRE);
int length = packetRE.getLength();
byte[] data = packetRE.getData();
System.out.println("收到B端的訊息:"+new String(data,0,length));
}
System.out.println("A端退出");
}
B端
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(9999);
while (true){
// 接收包並輸出訊息
byte []byteRE=new byte[1024];
DatagramPacket packetRE = new DatagramPacket(byteRE,byteRE.length);
datagramSocket.receive(packetRE);
System.out.println("收到A端");
int length = packetRE.getLength();
byte[] data = packetRE.getData();
String s = new String(data, 0, length);
System.out.println("收到A端的訊息:"+s);
if ("退出".equals(s)){
break;
}
// 傳送包併發送資料
System.out.println("傳送訊息");
Scanner scanner = new Scanner(System.in);
String content = scanner.next();
DatagramPacket packetSE = new DatagramPacket(content.getBytes(StandardCharsets.UTF_8), content.length(), InetAddress.getLocalHost(), 8888);
datagramSocket.send(packetSE);
}
System.out.println("B端退出");
}
注意點:
UDP網路程式設計沒有客戶端和服務端,都是用DatagramSocket接收和傳送,DatagramSocket可以設定不同端路自己的埠號
總結:
- 網路基礎知識方面要知道網路中,不同裝置的傳輸,需要IP地址,不同服務的傳輸需要埠號
- 可以通過InetAddress獲取本地的IP地址和埠號等資訊
- Socket套接字,底層是TCP/IP,在服務端和客戶端都有一個套接字,兩個端通過Socket的資料通道傳輸資料,記住客戶端也有埠號,並且是TCP/IP隨機分配的,我們可以通過套接字獲取到輸出和輸入的流,套接字會把流放進資料通道進行傳輸
- TCP網路程式設計,服務端需要獲取監聽,沒有收到客戶端的連線就會阻塞,然後通過套接字輸入流獲取客戶端傳來的資訊,客戶端需要獲取套接字並通過IP地址和埠號繫結到服務端,通過輸出流將資料輸出給服務端
- UDP網路程式設計,UDP沒有服務端和客戶端,只有接收端和傳送端,並且每一個端都可以是,通過物件DatagramSocket進行接收和傳送,通過Datagramapack進行封裝資料,接收端要拆包,設定接收的位元組陣列和長度,客戶端設定傳入的位元組陣列和IP地址,埠號