網路程式設計筆記

失措*發表於2020-12-02

socket

1.什麼是socket?

打電話–連線–通話 tcp

發簡訊–傳送—接收 udp

socket是一個介面底層實現了 作業系統對於tcp的連線

計算機網路:

​ 計算機網路指將地理位置不同的具有獨立功能的 多一臺計算機及其外部裝置通過網路線路銜接起來

如何定位到一個主機

​ 1.通過ip地址 : 埠

​ 2.如何傳輸資料?

2.http連線和socket連線的關係

多個http(長連線):connection:keep-alive(保持活躍) 請求會使用同一個socket,不會關閉socket

  • 還與tomcat 同時存在多少個活躍的 socket 有關(tomcat同時處理http請求的個數)

短連線:connection:close 在tomcat返回資料會關閉 socket

3.網路通訊的要素

如何實現網路的通訊?

通訊雙方的地址:

  • ip
  • 埠號

tcp協議: tcp位於傳輸層

img

​ 小結:

​ 1.兩個問題

  • 如何準確的定位到一個主機
  • 找到主機如何通訊

​ 2.網路程式設計要素

  • ip和埠號
  • 網路通訊協議

4.IP

ip地址: InetAddress

ip分類

  • IPV4/IPV6

    • ipv4 127.0.0.1 4個位元組組成
    • ipv6 128位,八個無符號整數
  • 公網-私網

    • 網際網路
    • 區域網 192.168.xxx
  • 域名

    • 為了記憶ip問題

5.埠

主要是計算機程式的程式;

  • 不同的程式有不同的埠號!
  • 埠規定為 0~65535
  • Tcp與Udp 可以使用同一個埠號
  • 埠分類
    • 共有埠 0~1023
      • Http:443
      • Http:80
      • Ftp:21
    • 程式註冊埠 1024~46151
      • Tomcat : 8080
      • mysql : 3306
      • Oracle : 1521

6. 協議

Tcp/IP協議–網路互聯協議

  • Tcp 使用者傳輸協議
    • 長連線,短連線
  • UDP 使用者資料包協議

image-20201201215259770

TCP與UDP對比:

TCP:

  • 三次握手 四次揮手

    最少需要三次才能保證穩定連線

    ​ A 傳送 B接收 B接收能力確認

    ​ B 傳送 A 接收 A傳送接收都可以

    ​ A 再傳送給B 確認 B傳送能力 ok

    揮手:(依依不捨,藕斷絲連)

    ​ A:我要斷開了

    ​ B : 我知道啦

    ​ B:真的斷開嗎

    ​ A : 真的斷開了

  • 連線穩定

  • 傳輸完成 釋放連結

UDP:

  • 連線不穩定
  • 客戶端 服務端沒有明確的界限
  • 不管準沒準備好都可以發給你

TCP

客戶端與伺服器(關閉socket和流!)

  • 1、客戶端要知道伺服器地址,服務端中 new ServerSocket(“9999” ) 開啟服務端埠
  • 2、埠號
  • 3、建立socket連線 new socket(ip,port)
  • 4、傳送訊息 IO流
/**
 * @author zbhou  on  2020/12/1 22:29
 * 客戶端
 */
public class TcpCline01 {
    public static void main(String[] args) throws IOException {
        //ip 與 埠號
        InetAddress host = InetAddress.getByName("127.0.0.1");
        int port=9999;
        //建立連線
        Socket socket = new Socket(host, port);
        //傳送訊息 IO
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello socket!".getBytes());

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

    }
}
/**
 * @author zbhou  on  2020/12/1 22:34
 * 服務端
 */
public class TcpServer01 {
    public static void main(String[] args) throws IOException {
        //建立連線
        ServerSocket serverSocket = new ServerSocket(9999); //建立服務埠號
        Socket socket=null;
        InputStream is=null;
        ByteArrayOutputStream out=null;

        try {
            //輪詢等待客戶端連線
            while(true){
                socket = serverSocket.accept();  //得到伺服器 socket,等待客戶的連線
                is = socket.getInputStream();//得到輸入流

                out = new ByteArrayOutputStream();//管道流
                byte[] bytes = new byte[1024];
                int len;
                while ((len=is.read(bytes))!=-1){
                    out.write(bytes,0,len);
                }
                System.out.println(out.toString());

            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //關閉連線
            out.close();
            is.close();
            socket.close();
            serverSocket.close();
        }

    }
}

image-20201201230027392

image-20201201225913553

7.檔案上傳

/**
 * @author zbhou  on  2020/12/1 23:20
 * 檔案上傳
 */
public class TcpCline02 {
    public static void main(String[] args) throws IOException {
        //建立連線
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        //讀檔案
        OutputStream os = socket.getOutputStream();
        //讀取檔案
        FileInputStream fis = new FileInputStream(new File("src/main/java/com/1.jpg"));
        //寫出檔案
        byte[] bytes = new byte[1024];
        int lth;
        while ((lth=fis.read(bytes))!=-1){
            os.write(bytes,0,lth);
        }

        //通知服務端傳送完畢
        socket.shutdownOutput();

        //接收服務端返回訊息,然後關閉
        InputStream is = socket.getInputStream();
        //讀取,因為不知道讀取型別,所以使用 管道流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] bytes1 = new byte[1024];
        int lth1;
        while ((lth1=is.read(bytes1))!=-1){
            byteArrayOutputStream.write(bytes1,0,lth1);
        }
        System.out.println(byteArrayOutputStream.toString());

        //關閉
        byteArrayOutputStream.close();
        is.close();
        fis.close();
        os.close();
        socket.close();
    }
}
/**
 * @author zbhou  on  2020/12/1 23:29
 * 上傳檔案 服務端
 */
public class TcpServer02 {
    public static void main(String[] args) throws IOException {
        //服務端
        ServerSocket serverSocket = new ServerSocket(9000);
        //獲得連線
        Socket socket = serverSocket.accept();
        //獲得檔案
        InputStream is = socket.getInputStream();

        FileOutputStream fos = new FileOutputStream(new File("src/main/java/com/2.jpg"));
        byte[] bytes = new byte[1024];
        int lth;
        while ((lth=is.read(bytes))!=-1){
            fos.write(bytes,0,lth);
        }

        //通知客戶端已經接收到訊息 可以關閉
        OutputStream os = socket.getOutputStream();
        os.write("服務端接收完畢!".getBytes());

        //關閉
        os.close();
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

8. Tomcat

服務端

  • 上面為自定義
  • 使用Tomcat

客戶端

  • 自定義
  • 瀏覽器

9.UDP

不需要連線伺服器,需要地址

1.建立scoket new DatagramSocket

2.建立包 new DatagramPacket 五個引數(字元,開始位置,結束位置,ip,port)

3.傳送包 socket.send( packet )

4.關閉

接收端

1.開放埠 new DatagramSocket(port)

2.接收

/**
 * @author zbhou  on  2020/12/2 0:29
 */
public class UDPCLine01 {
    public static void main(String[] args) throws IOException {
        //建立連線
        DatagramSocket datagramSocket = new DatagramSocket();
        //建立包
        String s="你好";
        DatagramPacket packet = new DatagramPacket(s.getBytes(), 0, s.getBytes().length, InetAddress.getByName("127.0.0.1"), 9999);
        //傳送
        datagramSocket.send(packet);

        datagramSocket.close();
    }
}
/**
 * @author zbhou  on  2020/12/2 0:34
 */
public class UDPServer01 {
    public static void main(String[] args) throws IOException {
        //設定埠
        DatagramSocket datagramSocket = new DatagramSocket(9999);
        //獲得
        byte[] bytes = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
        datagramSocket.receive(datagramPacket);  //阻塞接收

        System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
    }
}

-----------------------------------------------------------------------------------------來自B站狂神說的視訊

相關文章