1. 程式人生 > 遊戲資訊 >無悔華夏文物登場地點、繫結人物一覽表

無悔華夏文物登場地點、繫結人物一覽表

網路程式設計

概述

計算機網路:

計算機網路是指將地理位置不同的具有獨立功能的多臺計算機及其外部裝置,通過通訊線路連線起來,在網路作業系統,網路管理軟體及網路通訊協議的管理和協調下,實現資源共享和資訊傳遞的計算機系統。

網路程式設計的目的:傳播交流資訊(資料交換、通訊)

想要達到這樣的效果需要什麼:

  1. 如何準確的定位網路上的一臺主機: IP地址、埠號 ,定位到這個計算機上的某個資源

  2. 找到了這個主機,如何進行傳輸資料

 

網路程式設計: TCP/IP 協議 C/S架構

javaweb:網頁程式設計 B/S架構

 

C/S架構: 伺服器-客戶機( Server-Client ),即C/S結構。C/S結構通常採取兩層結構。伺服器負責資料的管理,客戶機負責完成與使用者的互動任務。

 

B/S架構: B/S架構即瀏覽器和伺服器架構模式,是隨著Internet技術的興起,對C/S架構架構/1050735)的一種變化或者改進的架構。在這種架構下,使用者工作介面是通過WWW瀏覽器來實現,極少部分事務,事務邏輯在前端(Browser)實現,但是主要事務邏輯在伺服器端(Server)實現,形成所謂三層3-tier結構。B/S架構是WEB興起後的一種網路架構模式,WEB瀏覽器是客戶端最主要的應用軟體。這種模式統一了客戶端,將系統功能實現的核心部分集中到伺服器上,簡化了系統的開發、維護和使用。客戶機上只要安裝一個瀏覽器(Browser),如Netscape Navigator或Internet Explorer,伺服器安裝Oracle、Sybase、Informix或 SQL Server等資料庫。瀏覽器通過Web Server同資料庫進行資料互動。 這樣就大大簡化了客戶端電腦載荷,減輕了系統維護與升級的成本和工作量,降低了使用者的總體成本(TCO)。

 

網路通訊的要素

如何實現網路的通訊:

  1. 通訊雙方地址( ip 埠號 192.168.0.100 139)

    比如:ping百度 可以得到百度伺服器的ip地址

     

  2. 規則:網路通訊協議(http、ftp、tcp.........)

     

 

小結:

  1. 網路程式設計中兩個主要的問題:

    • 如何準確的定位到網路上的一臺或多臺主機

    • 找到主機之後如何進行通訊

  2. 網路程式設計中的要素:

    • ip地址和埠號

    • 網路通訊協議

  3. 萬物皆物件

 

IP

ip地址:InetAddress(IP地址是由IP使用的32位或128位無符號數字,構建UDP和TCP協議的低階協議。

  • 唯一定位一臺網路上的計算機

  • 127.0.0.1 : 本機localhost

  • IP地址的分類

    • IPV4 / IPV6

      • IPV4:127.0.0.1 4個位元組組成 0~255 2011年就用盡

      • IPV6 : 128位 8個無符號整數 fe80::98ea:c2a3:f308:2719%42 (加了模運算,應該是8位的)

    • 公網(外網、網際網路) 私網(內網、區域網)

  • 域名:記憶IP問題

    IP:www.vip.com

 package com.network;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
 //測試IP
 public class TestInetAddress {
     public static void main(String[] args) throws UnknownHostException {
         InetAddress localHost = InetAddress.getLocalHost();
         System.out.println(localHost);
 
         InetAddress byName = InetAddress.getByName("www.baidu.com");
         System.out.println(byName);
 
         System.out.println("----------------");
 
         System.out.println(byName.getHostAddress());  //獲得ip
         System.out.println(byName.getHostName());     //獲得域名
    }
 }
 /*
 DESKTOP-DQRDJG2/192.168.0.100
 www.baidu.com/220.181.38.150
 ----------------
 220.181.38.150
 www.baidu.com
  */
 

 

埠表示計算機上的一個程式的程序:

  • 不同的程序有不同的埠號 埠號可用來區分軟體

  • 埠號的範圍被規定為:0~65535(2的16次方-1)

  • 其中,TCP,NCP 都有 總的埠就有:65536*2 單個協議下,埠號不能衝突

  • 埠分類:

    • 公有埠:0~1023 例如:

      HTTP : 80 HTTPS : 443 FTP : 21 Telent : 23

    • 程式註冊埠:1024~49151 分配使用者或者程式 例如:

      Tomcat :8080 MySQL:3306 Oracle:1521

    • 動態、私有埠:49152~65535

       netstat -ano  #檢視所在的埠
       netstat -ano|findstr "138"   #檢視指定的埠
       tasklist|findstr "40600"    #檢視指定埠的程序
       Ctrl + shift + ESC   #快捷鍵 開啟工作管理員

 

 package com.network;
 
 import java.net.InetSocketAddress;
 
 public class TestInetSocketAddress {
     public static void main(String[] args) {
         InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
         System.out.println(inetSocketAddress);
 
         System.out.println(inetSocketAddress.getAddress());
         System.out.println(inetSocketAddress.getHostName());
         System.out.println(inetSocketAddress.getPort());
    }
 }
 /*
 /127.0.0.1:8080
 /127.0.0.1
 127.0.0.1
 8080
  */
 

通訊協議

協議:約定

網路通訊協議:速率、傳輸位元速率、程式碼結構、傳輸控制......

問題非常複雜,解決的辦法:分層(上面有,TCP/IP 4層概念模型)

TCP/IP協議簇:實際上是一組協議

其中重要的是:

  • TCP:使用者傳輸協議

  • UDP:使用者資料報協議

其中出名的協議:

  • TCP:

  • IP:網路互連協議

TCP UDP 的對比:

TCP:相當於打電話 有連線 且穩定

三次握手 四次揮手

 形象比喻:
 
 連線最少需要三次,保證穩定連線
 A:你愁啥?
 B:瞅你咋地
 A:幹一架
 
 斷開連線需要四次
 A:我要走了
 B:你真的要走了嗎?
 B:你真的真的要走了嗎?
 A:我真的要走了啊

客戶端和服務端之間資料互動

傳輸完成,釋放連線 效率低

 

UDP:相當於發簡訊 不連線 不穩定

有客戶端 服務端:沒有明確的界限,客戶端可以和服務端互動,也可以客戶端和客戶端互動

不管有沒有連線好 都可以直接發給你

TCP

tcp實現聊天:

客戶端:Client

  1. 連線伺服器 Socket

  2. 傳送訊息

 package com.network;
 
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
 //客戶端
 public class TestClient {
     public static void main(String[] args) {
 
         Socket socket =null;
         OutputStream os =null;
         try {
             // 1.確定所連服務端的ip和埠號
             InetAddress localHost = InetAddress.getLocalHost();
             int port=9999;
             // 2.建立一個socket連線
             socket = new Socket(localHost, port);
             // 3.傳送訊息
             os = socket.getOutputStream();
             os.write("你好啊".getBytes());
        } catch (Exception e) {
             e.printStackTrace();
        }finally {
             if (os!=null){
                 try {
                     os.close();
                } catch (IOException e) {
                     e.printStackTrace();
                }
            }
             if (socket!=null){
                 try {
                     socket.close();
                } catch (IOException e) {
                     e.printStackTrace();
                }
            }
        }
    }
 }
 

 

服務端:Server

  1. 建立服務的埠 ServerSocket

  2. 等待使用者的連線 accept

  3. 接收使用者的訊息

 package com.network;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 
 //服務端
 public class TestServer {
     public static void main(String[] args) {
         ServerSocket serverSocket =null;
         Socket accept =null;
         InputStream is=null;
         ByteArrayOutputStream baos =null;
         try {
             // 1.得先有個地址
             serverSocket = new ServerSocket(9999);
             // 2.等待客戶端連線進來
             accept = serverSocket.accept();
             // 3.讀取客戶端傳送的訊息
             is = accept.getInputStream();
 
             // 管道流 接受
             baos = new ByteArrayOutputStream();
             byte[] buffer = new byte[1024];
             int len;
             while ((len=is.read(buffer))!=-1){
                 baos.write(buffer,0,len);
            }
 
             System.out.println(baos.toString());
        } catch (IOException e) {
             e.printStackTrace();
        }finally {
             //流 用完了關閉 先開後關
             if(baos!=null){
                 try {
                     baos.close();
                } catch (IOException e) {
                     e.printStackTrace();
                }
            }
             if (is!=null){
                 try {
                     is.close();
                } catch (IOException e) {
                     e.printStackTrace();
                }
            }
             if (accept!=null){
                 try {
                     accept.close();
                } catch (IOException e) {
                     e.printStackTrace();
                }
            }
             if (serverSocket!=null){
                 try {
                     serverSocket.close();
                } catch (IOException e) {
                     e.printStackTrace();
                }
            }
        }
    }
 }
 

先執行TestServer 在執行TestClient 然後TestServer 就收到了

 

 

tcp實現檔案上傳:

伺服器端:

 package com.network;
 
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 
 //服務端
 public class TestServer02 {
     public static void main(String[] args) throws Exception {
         //1. 有個地址 建立服務
         ServerSocket serverSocket = new ServerSocket(9955);
         //2. 等待客戶端的連線
         Socket accept = serverSocket.accept();
         //3. 獲取輸入流
         InputStream is = accept.getInputStream();
 
         //4.檔案接收輸出 管道流
         FileOutputStream fos = new FileOutputStream("csdn01.png");
         byte[] bytes = new byte[1024];
         int len;
         while ((len=is.read(bytes))!=-1){
             fos.write(bytes,0,len);
        }
 
         //通知客戶端 我接收完了
         OutputStream outputStream = accept.getOutputStream();
         outputStream.write("我接收完成".getBytes());
 
         //關閉資源
         outputStream.close();
         fos.close();
         is.close();
         accept.close();
         serverSocket.close();
    }
 }
 

客戶端:

 package com.network;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.Socket;
 
 //檔案的上傳
 //客戶端傳送給伺服器
 public class TestClient02 {
     public static void main(String[] args) throws Exception {
         //1.確定所連服務端的ip和埠號
         InetAddress byName = InetAddress.getByName("192.168.0.100");
         int port = 9955;
         //2.建立一個連線
         Socket socket = new Socket(byName, port);
         //3.建立一個輸出流
         OutputStream os = socket.getOutputStream();
 
         //4.讀取本機檔案
         FileInputStream fileIs = new FileInputStream("csdn.png");
         //5.寫出檔案
         byte[] buffer = new byte[1024];
         int len;
         while ((len=fileIs.read(buffer))!=-1){
             os.write(buffer,0,len);
        }
 
         //通知伺服器 我傳輸完了
         socket.shutdownOutput();
 
         //確定伺服器接收完畢,斷開連線
         InputStream inputStream = socket.getInputStream();
         //String byte[]
         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
         byte[] bytes = new byte[1024];
         int len2;
         while ((len2=inputStream.read(bytes))!=-1){
             byteArrayOutputStream.write(bytes,0,len2);
        }
 
         System.out.println(byteArrayOutputStream.toString());
         
         //關閉資源
         byteArrayOutputStream.close();
         inputStream.close();
         fileIs.close();
         os.close();
         socket.close();
         
    }
 }
 

 

UDP

udp相當於發簡訊 只需要傳送 不需要建立連線

public class DatagramSocket :此類表示用於傳送和接受資料報包的套接字

資料報套接字是分組傳送服務的傳送或接收點。 在資料報套接字上傳送或接收的每個資料包都被單獨定址和路由。 從一個機器傳送到另一個機器的多個分組可以不同地路由,並且可以以任何順序到達。

 

public final class DatagramPacket :此類表示資料報包

資料報包是用於實現無連線分組傳送服務。僅基於該資料包中包含的資訊,每個訊息從一臺機器路由到另一臺機器。 從一臺機器傳送到另一臺機器的多個分組可能會有不同的路由,並且可能以任何順序到達。 包傳送不能保證


udp傳送資訊

傳送端:

 package com.network;
 
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 
 //傳送端
 public class TestSend {
     public static void main(String[] args) throws Exception {
         //1.建立一個連線服務
         DatagramSocket datagramSocket = new DatagramSocket();
         //2.建包
         String msg="你好你好";
         //傳送給誰
         InetAddress localHost = InetAddress.getLocalHost();
         int port=9898;
         //3.傳送包
         DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localHost, port);
         datagramSocket.send(datagramPacket);
 
         //關閉資源
         datagramSocket.close();
    }
 }
 

接收端:

 package com.network;
 
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 
 //接收端
 public class TestReceive {
     public static void main(String[] args) throws Exception {
         //1. 開放埠
         DatagramSocket datagramSocket = new DatagramSocket(9898);
         //接收資料包
         byte[] bytes = new byte[1024];
         DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
 
         datagramSocket.receive(datagramPacket);   //阻塞接受
 
         System.out.println(datagramPacket.getAddress().getHostAddress());
         System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
         //關閉連線
         datagramSocket.close();
    }
 }
 

最後輸出結果:

 

udp實現聊天

初始程式碼:傳送方迴圈傳送 接收方可迴圈接受

傳送方:

 package com.network.udp.chat;
 
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetSocketAddress;
 
 //傳送方迴圈傳送
 public class Send01 {
     public static void main(String[] args) throws Exception {
         DatagramSocket datagramSocket = new DatagramSocket();
         //準備資料 控制檯讀取System.in
         while (true){
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
             String data=bufferedReader.readLine();
             if (data.equals("bye")){
                 break;
            }
             byte[] bytes = data.getBytes();
 
             DatagramPacket datagramPacket = new DatagramPacket(bytes,0 ,bytes.length ,new InetSocketAddress("localhost", 8866));
             datagramSocket.send(datagramPacket);
        }
         datagramSocket.close();
    }
 }
 

 

接收方:

 package com.network.udp.chat;
 
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 
 //接收方迴圈接收
 public class Receive01 {
     public static void main(String[] args) throws Exception {
         DatagramSocket datagramSocket = new DatagramSocket(8866);
         while (true){
             byte[] bytes = new byte[1024];
             DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
 
             datagramSocket.receive(datagramPacket);
 
             datagramPacket.getData();
 
             String s = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
             System.out.println(s);
             if (s.equals("bye")){
                 break;
            }
        }
         datagramSocket.close();
    }
 }
 

最後可以實現 控制檯迴圈輸入輸出

 

升級程式碼:通過多執行緒實現雙方聊天

傳送執行緒:

 package com.network.udp.chat;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetSocketAddress;
 
 public class TalkSend implements Runnable{
     DatagramSocket datagramSocket=null;
     BufferedReader bufferedReader =null;
 
     private String yourIP;
     private int yourPort;
 
     public TalkSend(String yourIP, int yourPort) {
         this.yourIP = yourIP;
         this.yourPort = yourPort;
 
         try {
             datagramSocket=new DatagramSocket();
             bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
             e.printStackTrace();
        }
    }
 
     @Override
     public void run() {
         //準備資料 控制檯讀取System.in
         while (true){
             String data= null;
             try {
                 data = bufferedReader.readLine();
            } catch (IOException e) {
                 e.printStackTrace();
            }
             if (data.equals("bye")){
                 break;
            }
             byte[] bytes = data.getBytes();
 
             DatagramPacket datagramPacket = new DatagramPacket(bytes,0 ,bytes.length ,new InetSocketAddress(yourIP, yourPort));
             try {
                 datagramSocket.send(datagramPacket);
            } catch (IOException e) {
                 e.printStackTrace();
            }
        }
         datagramSocket.close();
    }
 }
 

接收執行緒:

 package com.network.udp.chat;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.SocketException;
 
 public class TalkReceive implements Runnable {
     DatagramSocket datagramSocket=null;
 
     private int port;
     private String name;
 
     public TalkReceive(int port, String name) {
         this.port = port;
         this.name = name;
 
         try {
             datagramSocket = new DatagramSocket(port);
        } catch (SocketException e) {
             e.printStackTrace();
        }
    }
 
     @Override
     public void run() {
 
         while (true){
             byte[] bytes = new byte[1024];
             DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
 
             try {
                 datagramSocket.receive(datagramPacket);
            } catch (IOException e) {
                 e.printStackTrace();
            }
 
             datagramPacket.getData();
 
             String s = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
             System.out.println(name+" :"+s);
             if (s.equals("bye")){
                 break;
            }
        }
         datagramSocket.close();
    }
 }
 

學生端:

 package com.network.udp.chat;
 
 public class TalkStudent {
     public static void main(String[] args) {
         TalkSend send = new TalkSend("localhost", 8866);
         new Thread(send).start();
         TalkReceive receive = new TalkReceive(6688, "教師");
         new Thread(receive).start();
    }
 }
 

教師端:

 package com.network.udp.chat;
 
 public class TalkTeacher {
     public static void main(String[] args) {
         TalkSend send = new TalkSend("localhost", 6688);
         new Thread(send).start();
         TalkReceive receive = new TalkReceive(8866, "學生");
         new Thread(receive).start();
    }
 }
 

 

URL下載網路資源

https://www.baidu.com/

url:統一資源定位符,定位資源的,可以定位網際網路上的某一個資源

 url的組成:5部分  可以少 不可以多
 
 協議://ip地址:埠號/專案名/資源

url:

 package com.network;
 
 import java.net.MalformedURLException;
 import java.net.URL;
 
 public class TestUrl01 {
     public static void main(String[] args) throws MalformedURLException {
         URL url = new URL("https://www.baidu.com/");
         System.out.println(url.getPort());  //埠號
         System.out.println(url.getHost());  //ip
         System.out.println(url.getPath());  //檔案
         System.out.println(url.getFile());  //檔案全路徑
         System.out.println(url.getProtocol());  //協議
 
    }
 }
 /*
 -1
 www.baidu.com
 /
 /
 https
  */
 

url下載網路資源:

 package com.network;
 
 import javax.net.ssl.HttpsURLConnection;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
 
 
 public class TestUrl02 {
     public static void main(String[] args) throws IOException {
         //下載地址
         URL url = new URL("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png");
 
         //連線到這個資源 Https協議
         HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
 
         InputStream inputStream = urlConnection.getInputStream();
 
         FileOutputStream fileOutputStream = new FileOutputStream("baidu001.jpg");
 
         byte[] bytes = new byte[1024];
         int len;
         while ((len=inputStream.read(bytes))!=-1){
             fileOutputStream.write(bytes,0,len);  //寫出這個資料
        }
         fileOutputStream.close();
         inputStream.close();
         urlConnection.disconnect();  //不連線了 也相當於close
 
    }
 }