1. 程式人生 > >黑馬程式設計師--網路程式設計知識點總結

黑馬程式設計師--網路程式設計知識點總結

網路程式設計三要素

IP,埠,協議。

1.IP:在Internet上,每一臺通訊實體(這個通訊實體可以是路由器的某一埠,計算機和伺服器等裝置)都有唯一表示的IP地址,之前都是IPv4的但在2011年已經用盡,現在正向ipv6時代邁進

2.埠:在裝置上的唯一標識,範圍在0–65535之間,編寫網路應用就需要繫結一個埠號,儘量使用1024以上的,1024以下的基本上都被系統程式佔用了。

3.協議:為計算機網路中進行資料交換而建立的規則、標準或約定的集合。

UDP
面向無連線,資料不安全,速度快。不區分客戶端與服務端。
TCP
  面向連線(三次握手),資料安全,速度略低。分為客戶端和服務端。
三次握手: 客戶端先向服務端發起請求, 服務端響應請求, 傳輸資料

Socket套接字

網路上具有唯一標識的IP地址和埠號組合在一起才能構成唯一能識別的識別符號套接字。
通訊的兩端都有Socket。
網路通訊其實就是Socket間的通訊。
資料在兩個Socket間通過IO流傳輸。
Socket在應用程式中建立,通過一種繫結機制與驅動程式建立關係,告訴自己所對應的IP和port

UDP的傳輸

傳送Send
建立DatagramSocket, 隨機埠號
建立DatagramPacket, 指定資料, 長度, 地址, 埠
使用DatagramSocket傳送DatagramPacket
關閉DatagramSocket

public static void main(String[] args) throws IOException {
        String s = "為夢想奮鬥";//要傳送的資料
        DatagramSocket ds = new DatagramSocket();//建立Socket物件     相當於建立碼頭
        DatagramPacket dsp =                  //建立Packet 相當於建立集裝箱
                new DatagramPacket(s.getBytes(), s.getBytes().length,InetAddress.getByName("127.0.0.1"
),12345); ds.send(dsp); //傳送資料 ds.close(); }

接收Receive
建立DatagramSocket, 指定埠號
建立DatagramPacket, 指定陣列, 長度
使用DatagramSocket接收DatagramPacket
關閉DatagramSocket
從DatagramPacket中獲取資料

public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(12345);        //建立Socket相當於建立一個碼頭
        DatagramPacket packet = new DatagramPacket(new byte[1024],1024);//建立Packet相當於建立一個集裝箱
        socket.receive(packet);

        byte[] arr = packet.getData();                   //從集裝箱中獲取資料
        int len = packet.getLength();                   //獲取發過來的有效位元組個數
        System.out.println(new String(arr,0,len));

        socket.close();
    }

UDP傳輸的優化

public static void main(String[] args) throws IOException {

        DatagramSocket ds = new DatagramSocket();//建立Socket物件     相當於建立碼頭
        Scanner sc = new Scanner(System.in);//鍵盤錄入
        while(true){
            String line = sc.nextLine();//接收鍵盤錄入內容
            if("over".equals(line)){    //相當於圖形化介面的差號
                break;
            }
            DatagramPacket dsp =                  //建立Packet 相當於建立集裝箱
                new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("127.0.0.1"),12345);
            ds.send(dsp);                    //傳送資料

        }
        ds.close();
    }
public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(12345);        //建立Socket相當於建立一個碼頭
        DatagramPacket packet = new DatagramPacket(new byte[1024],1024);//建立Packet相當於建立一個集裝箱
        while(true){

        socket.receive(packet);

        byte[] arr = packet.getData();                   //從集裝箱中獲取資料
        int len = packet.getLength();                   //獲取發過來的有效位元組個數
        String ip = packet.getAddress().getCanonicalHostName();//獲取IP地址
        int port = packet.getPort();                     //獲取埠號
        System.out.println(ip + ":" + port + ":" + new String(arr,0,len));

        }

    }

}

TCP傳輸
客戶端
普通方式和優化方式

public static void main(String[] args) throws UnknownHostException, IOException {
        //demo();
        Socket socket = new Socket("127.0.0.1",9999);//建立Socket,並指定IP和埠號
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//對輸入流包裝
        PrintStream ps = new PrintStream(socket.getOutputStream());

        ps.println("相信自己一定可以");//向伺服器寫出資料
        System.out.println(br.readLine());//讀取伺服器的內容並列印

        socket.close();
    }

    private static void demo() throws UnknownHostException, IOException {
        Socket socket = new Socket("127.0.0.1",9999);//建立Socket,並指定IP和埠號
        InputStream is = socket.getInputStream();
        OutputStream os = socket.getOutputStream();

        byte[] arr = new byte[1024];
        int len = is.read(arr);
        System.out.println(new String(arr,0,len));

        os.write("只要是我夢想的,就一定能實現".getBytes());
    }

}

服務端

普通方式

private static void demo() throws IOException {
        ServerSocket server = new ServerSocket(9999);//建立ServerSocket t物件並連線埠
        Socket socket = server.accept();              //接收客戶端的請求

        InputStream is = socket.getInputStream();      //獲取輸入流
        OutputStream os = socket.getOutputStream();// 獲取輸出流

        os.write("努力學習".getBytes());       //字串寫到客戶端

        byte[] arr = new byte[1024];     //建立位元組陣列
        int len = is.read(arr);           //將資料讀取到位元組陣列中
        System.out.println(new String(arr,0,len));//將陣列轉化為字串

        server.close();
        socket.close();
    }

優化方式

private static void demo1() throws IOException {
        ServerSocket server = new ServerSocket(9999);//建立ServerSocket t物件並連線埠
        Socket socket = server.accept();              //接收客戶端的請求

        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//對輸入流包裝
        PrintStream ps = new PrintStream(socket.getOutputStream());

        System.out.println(br.readLine());//讀取伺服器的內容並列印
        ps.println("加油加油加油");         //向伺服器寫出資料

        socket.close();//關閉套接字,順便關閉流
    }

多執行緒方式

public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(9999);//建立ServerSocket t物件並連線埠
        while(true){
            final Socket socket = server.accept();   //接收客戶端的請求
            new Thread(){
                public void run(){

                    try {
                        BufferedReader br= new BufferedReader(new InputStreamReader(socket.getInputStream()));//對輸入流包裝
                        PrintStream ps = new PrintStream(socket.getOutputStream());


                        System.out.println(br.readLine());//讀取伺服器的內容並列印
                        ps.println("努力努力努力");         //向伺服器寫出資料

                        socket.close();//關閉套接字,順便關閉流
                    } catch (IOException e) {

                        e.printStackTrace();
                    }
                }
            }.start();

練習:客戶端向伺服器寫字串,伺服器將字串反轉後寫回,客戶端再次讀取到是反轉後的字串

客戶端:

public static void main(String[] args) throws UnknownHostException, IOException {
        Socket socket = new Socket("127.0.0.1", 23445);//建立客戶端物件並指定IP和埠
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream());

        Scanner sc = new Scanner(System.in);

        ps.println(sc.nextLine());       //將鍵盤錄入的字串放在伺服器中
        System.out.println(br.readLine());//列印反轉後的字串

        socket.close();

    }

服務端:

public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(23445);//建立服務端伺服器,並連線埠
        System.out.println("伺服器啟動");

        while(true){
            final Socket socket = server.accept();//接受客戶端的資料
            new Thread(){
                public void run(){
                    try {
                        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        PrintStream ps = new PrintStream(socket.getOutputStream());

                        String line = br.readLine();//獲取字串
                        line = new StringBuilder(line).reverse().toString();//將字串放在Stringbuilder中反轉並轉回字串

                        socket.close();
                    } catch (IOException e) {

                        e.printStackTrace();
                    }   
                }
            }.start();



        }