Java基础学习 ---网络编程

141 阅读5分钟

网络编程

Java基础学习---点击进入学习

640 (4).png

网络编程

1.IP地址

IP地址(Internet Protocol) 唯一标识网络上的每一台计算机

IP地址的组成 IPV4:32位,由4个8位二进制数组成

IPV6: 128位 十六进制的数据组成

2. 端口号

端口号标识正在计算机上运行的进程(程序)

不同的进程有不同的端口号

被规定为一个 16 位的整数 0-65535。

端口分类:

公认端口:0-1023。被预先定义的服务通信占用(如:HTTP占用端口80,FTP占用端口21,Telnet占用端口23)

注册端口:1024--49151。分配给用户进程或应用程序。(如:Tomcat占用端口8080,MySQL占用端口3306,Oracle占用端口1521等)。

动态/私有端口:49152-65535。

3. DNS

DNS:Domain Name System,域名系统

是一个分布式的数据库,负责将输入的域名解析为对应的IP地址

4. 网络5层/7层模型

网络7层模型太过理想化,最终未被实现,最终实现的是5层模型

七层模型.png

5.Socket

端口号与IP地址的组合得出一个网络套接字:Socket。

Socket是多个计算机之间进行网络通信的载体。

6.基于TCP协议的网络编程

TCP的面向连接的 安全的 可靠的传输协议


import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 14:25
 *  服务器
 *
 *  ServerSocket类实现
 *
 */
public class Server {
    public static void main(String[] args) {
        System.out.println("服务器启动……………………");
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedReader reader = null;
        InputStream inputStream = null;
        try {
            // 创建服务器对象 在8899端口号监听
            serverSocket =  new ServerSocket(8899);

            // 接收请求 获取到Socket对象
            socket = serverSocket.accept();

            // 通过Socket对象获取到字节读取流
            inputStream = socket.getInputStream();

            reader = new BufferedReader(new InputStreamReader(inputStream));

            System.out.println("客户端发送的信息为:" + reader.readLine());

            OutputStream outputStream = socket.getOutputStream();

            outputStream.write("hello  客户端".getBytes());

            socket.shutdownOutput();


        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(reader != null){
                    reader.close();
                }
                if(inputStream != null){
                    inputStream.close();
                }
                if(socket != null){
                    socket.close();
                }
                if(serverSocket != null){
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


import java.io.*;
import java.net.Socket;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 14:25
 *  客户端
 *
 *  Socket类实现
 *
 */
public class Client {
    public static void main(String[] args) {

        try {
            // 创建Socket对象 用于发送数据
            // localhost 以及 127.0.0.1 都表示本机
            Socket socket = new Socket("localhost",8899);

            // 通过Socket对象获取到字节写入流
            OutputStream outputStream = socket.getOutputStream();

            // 给服务器发送数据
            outputStream.write("你好啊,服务器".getBytes());

            // 关闭写入流 必须书写 相当于通知给服务器 发送完毕 服务器才能获取到这个状态 可以读取数据
            socket.shutdownOutput();

            InputStream inputStream = socket.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            System.out.println("服务器响应的内容为:" + reader.readLine());


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

7. 多客户端访问服务器

多个客户端访问同一个服务器,服务器需要单独分配不同的线程来处理客户端的请求。


import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 15:03
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8899);

        while(true){
            Socket socket = server.accept();
            new ServerThread(socket).start();
        }

    }
}


import java.io.*;
import java.net.Socket;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 15:05
 *  处理请求的线程类
 */
public class ServerThread extends Thread {
    private Socket socket;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream inputStream = socket.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            System.out.println("客户端发送的信息为:" + reader.readLine());

            OutputStream outputStream = socket.getOutputStream();

            outputStream.write("别问了,睡了".getBytes());

            socket.shutdownOutput();


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


    }
}


import java.io.*;
import java.net.Socket;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 15:02
 *  客户端1
 */
public class Client1 {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 8899);

        OutputStream outputStream = socket.getOutputStream();

        outputStream.write("睡了吗?".getBytes());

        socket.shutdownOutput();

        InputStream inputStream = socket.getInputStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

        System.out.println("客户端的回话是:"  + reader.readLine());

    }
}


import java.io.*;
import java.net.Socket;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 15:02
 *  客户端1
 */
public class Client2 {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 8899);

        OutputStream outputStream = socket.getOutputStream();

        outputStream.write("真的睡了吗?".getBytes());

        socket.shutdownOutput();

        InputStream inputStream = socket.getInputStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

        System.out.println("客户端的回话是:"  + reader.readLine());


    }
}


import java.io.*;
import java.net.Socket;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 15:02
 *  客户端1
 */
public class Client3 {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 8899);

        OutputStream outputStream = socket.getOutputStream();

        outputStream.write("确定睡了吗?".getBytes());

        socket.shutdownOutput();

        InputStream inputStream = socket.getInputStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

        System.out.println("客户端的回话是:"  + reader.readLine());


    }
}

8.TCP协议三次握手四次挥手

TCP需要三次握手建立连接,四次挥手断开连接,过程非常复杂,麻烦,但是通过这种方式可以保证数据的安全性。

TCP协议的三次握手:

​ 第一次:客户端向服务器发送连接请求

​ 第二次:服务器向客户端响应连接请求

​ 第三次:客户端与服务器建立连接

TCP协议的四次挥手:

​ 第一次:客户端向服务器发送断开连接请求

​ 第二次:服务器向客服端响应收到断开连接请求(因为TCP连接是双向的,所以此时服务器依然可以 向客户端发送信息)

​ 第三次:客户端等待服务器发送信息完成,向服务器确定全部信息发送完毕,并且断开客户端与服务器的连接

​ 第四次:服务器向客户端断开连接

三次握手.png

四次挥手.png

9.UDP协议编程

UDP 用户数据报协议 非面向连接的 不安全 不可靠的 但是效率高的传输协议



import java.io.IOException;
import java.net.*;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 15:28
 *  基于UDP协议的数据传输
 *
 *  DataGramPacket实现
 */
public class Client {
    public static void main(String[] args) throws IOException {
        // 定义发送信息的字符串
        String msg = "hello ,服务器";

        // 将字符串转换为byte数组
        byte[] data = msg.getBytes();

        // 根据字符串获取到InetAddress对象
        InetAddress localhost = InetAddress.getByName("localhost");

        // 构造DataGramPacket 对象 用于保存数据
        DatagramPacket sendPacket = new DatagramPacket(data,data.length,localhost,8899);

        // 创建Socket对象 用于发送数据包
        DatagramSocket socket = new DatagramSocket();

        // 发送数据
        socket.send(sendPacket);

        System.out.println("-------------------------开始读取数据-----------------------------");

        byte [] receiveData = new byte[10];

        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

        socket.receive(receivePacket);

        byte[] byteData = receivePacket.getData();

        System.out.println(new String(byteData,0,byteData.length));


    }
}


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/26 15:31
 *  服务器
 *  DataGramSocket实现
 */
public class Server {
    public static void main(String[] args) throws IOException {
        // 创建Socket对象 用于接收数据报包
        DatagramSocket socket = new DatagramSocket(8899);

        // 定义数组长度为8 表示可以接收8个字节的数据
        byte [] bag = new byte[8];

        // 构造DataGramPacket对象 用于保存数据
        DatagramPacket receivePacket = new DatagramPacket(bag,bag.length);

        // 接收数据 数据将保存在 DataGramPacket对象中
        socket.receive(receivePacket);

        // 调用getData()方法 获取数据
        byte[] data = receivePacket.getData();

        // 将获取到数据 转换为字符串
        System.out.println(new String(data,0,data.length));

        System.out.println("-------------------开始回复信息------------------------");

        String msg = "你好呀 客户端 ";

        byte [] sendData  = msg.getBytes();

        SocketAddress socketAddress = receivePacket.getSocketAddress();

        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, socketAddress);

        socket.send(sendPacket);

    }
}