【狂神說Java】網路程式設計

ChanV233發表於2020-12-10

網路程式設計

1.1、概述

**地球村:**你在西安,你一個美國的朋友!

信件:

計算機網路:

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

網路程式設計的目的:

無線電臺…傳播交流資訊,資料交換。通訊

想要達到這個效果需要什麼:

  1. 如何準確地定位網路上的一臺主機 192.168.16.124:埠,定位到這個計算機上的某個資源
  2. 找到了這個主機,如何傳輸資料呢?

javaweb:網頁程式設計 B/S

網路程式設計:TCP/IP C/S

1.2、網路通訊的要素

如何實現網路的通訊?

通訊雙方地址:

  • ip
  • 埠號
  • 192.168.16,124:5900

規則:網路通訊的協議

TCP/IP參考模型:
img
在這裡插入圖片描述
小結:

  1. 網路程式設計中主要有兩個問題
  • 如何準確的定位到網路上的一臺或者多臺主機
  • 找到主機之後如何進行通訊
  1. 網路程式設計中的要素
  • IP和埠號 IP
  • 網路通訊寫協議 UDP,TCP
  1. 萬物皆物件

1.3、IP

ip地址:inetAddress

  • 唯一定位一臺網路上的計算機
  • 127.0.0.1:本機localhost
  • ip地址的分類
    • ipv4/ipv6
      • **IPV4:**127.0.0.1,四個位元組組成。0 ~ 255, 42億~;30億都在北美,亞洲4億。2001年就用盡了;
      • **IPV6:**fe80::755f:fc6c:2ebc:b6e6%18,128位。8個無符號整數!
		2001:0bb2:aaaa:0015:0000:0000:1aaa:1312
  • IP地址分類

  • 公網(網際網路)-私網(區域網)

    • ABCD類地址

    • 192.168.xx.xx,專門給組織內部使用的

  • 域名:記憶 IP問題!

    • IP:www.vip.com
public class TestInetAddress {

    public static void main(String[] args) {
   // write your code here
        try {
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            System.out.println(inetAddress1);
            InetAddress inetAddress3 = InetAddress.getByName("localhost");
            System.out.println(inetAddress3);
            InetAddress inetAddress4 = InetAddress.getLocalHost();
            System.out.println(inetAddress4);

            //查詢網站ip地址
            InetAddress inetAddress2 = InetAddress.getByName("www.bilibili.com");
            System.out.println(inetAddress2);

            //常用方法
            //System.out.println(inetAddress2.getAddress());
            System.out.println(inetAddress2.getCanonicalHostName());    //規範的名字
            System.out.println(inetAddress2.getHostAddress());  //ip
            System.out.println(inetAddress2.getHostName()); //域名,或者自己電腦的名字

        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

1.4、埠

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

  • 不同的程式有不同的埠號!用來區分軟體!
  • 被規定0 ~ 065535
  • TCP,UDP:65535 * 2 ,單個協議下,埠號不能衝突
  • 埠分類
    • 公有埠0 ~ 1023
      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telent:23
    • 程式註冊埠:1024 ~ 49151,分配給使用者或者程式
      • Tomcat:8080
      • MySQL:3306
      • Oracle:1512
    • 動態、私有:49152 ~ 65535
netstat -ano #檢視所有的埠
netstat -ano | finstr "5900" #檢視指定的埠
tasklist | findstr "8696" #檢視指定埠的程式
ctrl + shift + ESC
public class TestSocketAddress {
    public static void main(String[] args) {
        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
        System.out.println(socketAddress);

        System.out.println(socketAddress.getAddress());
        System.out.println(socketAddress.getHostName());
        System.out.println(socketAddress.getPort());
    }
}

1.5、通訊協議

協議:約定,就好比我們現在說的是普通話。

**網路通訊協議:**速率,傳輸位元速率,傳輸控制……

**問題:**非常的複雜?

大事化小:分層!

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

重要:

  • TCP:使用者傳輸協議
  • UDP:使用者資料包協議

出名的協議:

  • TCP:
  • IP:網路互連協議

在這裡插入圖片描述
TCP UDP對比

TCP:打電話

  • 連線,穩定
  • 三次握手 四次揮手
最少需要三次,保證穩定連線!
A:你瞅啥?
B:瞅你咋地?
A:幹一場!


A:我要走了
B:你真的要走了嗎?
B:你真的真的要走了嗎?
A:我真的要走了
  • 客戶端、服務端
  • 傳輸完成,釋放連線,效率低

UDP:發簡訊

  • 不連線,不穩定
  • 客戶端、服務端:沒有明確的界限
  • 不管有沒有準備好,都可以發給你…
  • 導彈攻擊
  • DDOS:洪水攻擊!(飽和攻擊)

1.6、TCP

客戶端

  1. 連線伺服器Socket
  2. 傳送訊息
//客戶端
public class tcpClientDemo01 {
    public static void main(String[] args) {

        Socket socket = null;
        OutputStream os = null;


        try {
            //1、要知道伺服器的地址,埠號
            InetAddress serverIP = InetAddress.getByName("127.0.0.1");
            int port = 9999;
            //2、建立一個socket連線
            socket = new Socket(serverIP, port);
            //3、傳送訊息 IO流
            os = socket.getOutputStream();
            os.write("Hello World".getBytes());

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

伺服器

  1. 建立服務的埠ServerScoket
  2. 等待使用者的連線accept
  3. 接收使用者的訊息
//服務端
public class tcpServerDemo01 {
    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;

        try {
            //1、我得有一個地址
            serverSocket = new ServerSocket(9999);
            //2、等待客戶端連線過來
            socket = serverSocket.accept();
            //3、讀取客戶端的訊息
            is = socket.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 (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (serverSocket != null){
                serverSocket.close();
            }
        }
    }
}

檔案上傳

伺服器端:

public class tcpServerDemo02 {
    public static void main(String[] args) throws Exception {
        //1、建立服務
        ServerSocket serverSocket = new ServerSocket(9999);
        //2、監聽客戶端的連線
        Socket socket = serverSocket.accept();  //阻塞式監聽,會一直等待客戶端連線
        //3、獲取輸入流
        InputStream is = socket.getInputStream();
        //4、檔案輸出
        FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1){
            fos.write(buffer, 0, len);
        }

        //通知客戶端我接收完畢了
        OutputStream os = socket.getOutputStream();
        os.write("我接受完畢了,你可以斷開了".getBytes());

        //5、關閉資源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}
public class tcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        //1、建立一個Socket連線
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
        //2、建立一個輸出流
        OutputStream os = socket.getOutputStream();
        //3、讀取檔案
        FileInputStream fis = new FileInputStream(new File("111.jpg"));
        //4、寫出檔案
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1){
            os.write(buffer, 0 , len);
        }

        //通知伺服器,我已經結束了
        socket.shutdownOutput();    //我已經傳輸完了!
        
        //確定伺服器接收完畢,才能夠斷開連線
        InputStream inputStream = socket.getInputStream();
        //String byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while ((len2 = inputStream.read(buffer2)) != -1){
            baos.write(buffer2, 0, len2);
        }
        System.out.println(baos.toString());

        //5、關閉資源
        baos.close();
        inputStream.close();
        fis.close();
        os.close();
        socket.close();
    }
}

Tomcat

服務端

  • 自定義 S
  • Tomcat伺服器 S:Java後臺開發!

客戶端

  • 自定義 C
  • 瀏覽器 B

1.7、UDP

發簡訊:不用連線,需要知道對方的地址

傳送訊息

//不需要連線伺服器
public class UdpClientDemo01{
    public static void main(String[] args) throws Exception{
        //1、建立一個Socket
        DatagramSocket socket = new DatagramSocket();

        //2、建一個包
        String msg = "你好啊,伺服器!";
        //傳送給誰
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;

        //資料,資料的長度起始,要傳送給誰
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);

        //3、傳送一個包
        socket.send(packet);

        //4、關閉流
        socket.close();
    }
}

接收端

//還是要等待客戶端的連線!
public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception{
        //開發埠
        DatagramSocket socket = new DatagramSocket(9090);
        //接收資料包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);   //接收

        socket.receive(packet); //阻塞接收

        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(), 0, packet.getLength()));

        //關閉連線
        socket.close();
    }
}

迴圈傳送訊息

XXX:你好!

YYY:你好!

public class UdpSenderDemo01 {
    public static void main(String[] args) throws Exception{
        DatagramSocket socket = new DatagramSocket(8888);

        //準備資料:控制檯讀取 System.in

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        while (true){
            String data = reader.readLine();
            byte[] datas = data.getBytes();
            DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));

            socket.send(packet);
            if (data.equals("bye")){
                break;
            }

        }

        socket.close();
    }
}
public class UdpReceiveDemo01 {
    public static void main(String[] args)  throws Exception{
        DatagramSocket socket = new DatagramSocket(6666);

        //準備接收包裹
        byte[] container = new byte[1024];

        while (true){
            DatagramPacket packet = new DatagramPacket(container, 0, container.length);
            socket.receive(packet); //阻塞式接收包裹

            //斷開連線 byte
            byte[] data = packet.getData();
            String receiveData = new String(data, 0, data.length);
            System.out.println(receiveData);

            if (receiveData.equals("bye")){
                break;
            }

        }
        socket.close();
    }
}

線上諮詢:兩個人都可以是傳送方,也可以是接收方!**

1.8、URL

https://www.baidu.com

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

DNS域名解析 www.baidu.com xxx.x.xx.xx

協議://ip地址:埠/專案名/資源

相關文章