黑马程序员--网络编程知识点总结

时间:2022-06-10 11:59:42



——- android培训java培训、期待与您交流! ———-

网络编程三要素

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();



        }