• JavaSE 基础(十三)网络编程


    1. 概述

    计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统网络管理软件网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

    网络编程主要工作是在发送端把信息通过规定好的协议进行组装包,在接收端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的。

    网络编程的主要问题:

    • 如何准确定位到网络上一台或多台主机
    • 定位到主机后如何进行通信

    网络网络编程要素:IP,端口号,UDP通信协议,TCP通信协议。

    2. IP

    IP 可唯一定位一台网络上的计算机。

    本机 IP 地址为 localhost:127.0.0.1

    Java 中 使用 InetAddress 类表示Internet协议(IP)地址。

    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class TestInetAddress {
        public static void main(String[] args) throws UnknownHostException {
            // 查询本机地址
            InetAddress inetAddr1 = InetAddress.getByName("127.0.0.1");
            InetAddress inetAddr2 = InetAddress.getByName("localhost");
            InetAddress inetAddr3 = InetAddress.getLocalHost();
            System.out.println(inetAddr1);
            System.out.println(inetAddr2);
            System.out.println(inetAddr3);
    
            // 查询网站 ip 地址
            InetAddress inetAddr4 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddr4);
    
            // 常用方法
            System.out.println(inetAddr4.getCanonicalHostName());   // 规范名
            System.out.println(inetAddr4.getHostAddress());  // IP
            System.out.println(inetAddr4.getHostName());    // 域名
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3. PORT

    端口设备与外界通讯交流的出口。

    命令行查看端口命令

    # 查看所有端口
    netstat -ano
    # 查看指定端口
    tasklist|findstr "80"
    # 查看指定端口的进程
    tasklist|findstr "80"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Java InetSocketAddress

    public class TestInetSocketAddress {
    
        public static void main(String[] args) {
            InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
            InetSocketAddress socketAddress1 = new InetSocketAddress("localhost", 8080);
            System.out.println(socketAddress);
            System.out.println(socketAddress1);
            System.out.println(socketAddress.getAddress());
            System.out.println(socketAddress.getHostName());
            System.out.println(socketAddress.getPort());
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4. 通信协议

    TCP/IP 协议

    在这里插入图片描述

    TCPUDP
    是否连接面向连接面向非连接
    传输可靠性可靠不可靠
    应用场合少量数据传输大量数据
    速度

    三次握手

    (1) 建立连接时,客户端发送syn包(seq=j)到服务器,并进入SYN_SENT状态,等待服务器确认。

    (2) 服务器收到syn包,必须确认客户端的SYN(ack=j+1),同时自己也发送一个SYN包(seq=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。

    (3) 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

    完成三次握手,客户端与服务器开始传送数据

    在这里插入图片描述

    四次挥手

    (1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送

    (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。

    (3) 服务器关闭客户端的连接,发送一个FIN给客户端。

    (4) 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。

    在这里插入图片描述

    5. TCP

    通信

    客户端

    • 连接服务器
    • 发送消息
    /**
     * TODO
     * 客户端
     * @author why
     * @since 2021/11/11 14:19
     */
    public class Client {
        public static void main(String[] args) {
    
            InetAddress serverIp = null;
            OutputStream os = null;
            try {
                // 1. 服务器 IP,PORT
                serverIp = InetAddress.getByName("127.0.0.1");
                int port = 9999;
                // 2. 创建 Socket 连接
                Socket socket = new Socket(serverIp, port);
                // 3. 发送消息
                 os = socket.getOutputStream();
                os.write("hello!".getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    服务端

    • 建立服务端口
    • 等待连接
    • 接收消息
    /**
     * TODO
     * 服务端
     * @author why
     * @since 2021/11/11 14:19
     */
    public class Server {
        public static void main(String[] args) {
    
            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) {
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    文件上传

    服务端

    /**
     * TODO
     * 服务端
     * @author why
     * @since 2021/11/11 15:15
     */
    public class Server {
        public static void main(String[] args) throws IOException {
            // 1. 创建服务
            ServerSocket serverSocket = new ServerSocket(9999);
            // 2. 监听客户端连接
            Socket socket = serverSocket.accept();
            // 3. 获取输入流
            InputStream is = socket.getInputStream();
            // 4. 文件输出
            FileOutputStream fos = new FileOutputStream(new File("./resources/receive/test.txt"));
            byte[] buffer = new byte[1024];
            int len;
            while ((len=is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
    
            // 5. 通知客户端接收完毕
            OutputStream os = socket.getOutputStream();
            os.write("receive over !".getBytes());
    
            // 6. 关闭资源
            fos.close();
            is.close();
            socket.close();
            serverSocket.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    客户端

    /**
     * TODO
     * 客户端
     * @author why
     * @since 2021/11/11 15:09
     */
    public class Client {
        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("./resources/send/test.txt"));
            // 4. 写出文件
            byte[] buffer = new byte[1024];
            int len;
            while ((len=fis.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            // 5. 传输完毕
            socket.shutdownOutput();
            // 6. 确认服务器接收完毕
            InputStream is = socket.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] infoBuffer = new byte[1024];
            int infoLen;
            while ((infoLen=is.read(infoBuffer)) != -1) {
                baos.write(infoBuffer, 0, infoLen);
            }
            System.out.println(baos.toString());
            // 7. 关闭资源
            baos.close();
            is.close();
            fis.close();
            os.close();
            socket.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    6. UDP

    发送端

    /**
     * TODO
     * UDP 客户端,不需要建立连接
     * @author why
     * @since 2021/11/11 16:04
     */
    public class Client {
        public static void main(String[] args) throws IOException {
            // 1. 建立 Socket
            DatagramSocket socket = new DatagramSocket();
            // 2. 建立一个包
            String msg = "Hello!";
            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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    接受端

    /**
     * TODO
     * UDP 服务端
     * @author why
     * @since 2021/11/11 16:10
     */
    public class Server {
        public static void main(String[] args) throws IOException {
            // 1. 开放端口
            DatagramSocket socket = new DatagramSocket(9090);
            // 2. 接收数据包
            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.getData().length));
            // 2. 关闭连接
            socket.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    7. URL

    统一资源定位符:定位互联网资源。

    DNS 域名解析:将 ip 映射成为域名,或将域名解析为 ip。

    构成 :协议://ip:端口/项目名/资源

  • 相关阅读:
    设置 mac 允许远程电脑 SSH 登录
    什么是Boot Guard?电脑启动中的信任链条解析
    Redis入门到实战(四、原理篇)RESP协议
    salesforce的按钮执行js代码如何链接到apex代码
    Unity实现角色受到攻击后屏幕抖动的效果
    oak深度相机入门教程-行人识别
    Ext JS适用于哪些开发场景?
    学习尚硅谷HTML+CSS总结
    WeChat Subscribers Lite - 微信公众订阅号自动回复WordPress插件
    2022年最新河北建筑八大员(机械员)模拟考试题库及答案
  • 原文地址:https://blog.csdn.net/qq_42651415/article/details/133294449