网络编程

350 阅读7分钟

Socket

什么是网络编程

  • 在网络通信协议下,不同计算机上运行的程序,进行的数据传输.
  • 应用场景:即时通信,网游对战.金融证券,国际贸易,邮件,等等.
  • 不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输.
  • java中可以使用java.net包下的技术轻松开发出常见的网络应用程序.

网络编程三要素

  • ip:设备在网络中的地址,是唯一的标识.
  • 端口号:应用程序在设备中唯一的标识.
  • 协议:数据在网络中传输的规则,常见的协议有UDP,TCP,HTTP,HTTPS,FTP.

ip

全称:Internet Protocol,是互联网协议地址,也称ip地址.是分配给上网设备的数字标签.上网设备在网络中的地址,是唯一的.

常见的分类:IPv4,IPv6

IPv4
  • IPv4(Internet Protocol version4,互联网通信协议第四版)
  • 采用32位地址长度,分成4组

微信截图_20240802094835.png

IPv4的地址分类

  • 公网地址(万维网使用)和私有地址(局域网使用).
  • 192.168.开头的就是私有地址,范围即为192.168.0.0-192.168.255.255,专门为组织机构内部使用,以此节省IP

特殊IP地址

  • 127.0.0.1也可以是localhost,是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在的本机.
IPv6
  • IPv6(Internet Protocol version6,互联网通信协议第六版)由于互联网的蓬勃发展,IP地址的需求量愈来愈大,而在IPv4模式下IP的总数是有限的.
  • 采用128位地址长度,分成8组

微信截图_20240802095237.png

InetAddress类
public class InetAddressTest {
    public static void main(String[] args) throws UnknownHostException {
        //确定主机名称的IP地址,主机名称可以是机器名称,也可以是IP地址
        InetAddress byName = InetAddress.getByName("192.168.3.2");
        System.out.println(byName);
        //获取此IP的主机名
        String hostName = byName.getHostName();
        System.out.println(hostName);
        //返回文本显示中的IP地址字符串
        String ip = byName.getHostAddress();
        System.out.println(ip);
    }
}

端口号

  • 应用程序在设备中唯一的标识.
  • 端口号:由两个字节表示的整数,取值范围0-65535
  • 其中0-1023之间的端口号用于一些知名网络服务或者应用.
  • 我们自己使用1024以上的端口号就可以了

协议

  • 计算机网络中,连接和通信的规则被称为网络通信协议
  • OSI参考模型:世界互联协议标准,全球通信规范,单模型过于理想化,未能在因特网上进行广泛推广
  • TCP/IP参考模型(或TCP/IP协议)事实上的国际标准.

微信截图_20240802104816.png

微信截图_20240802105449.png

UDP协议

单播

/**
 * @ClassName SendMessage
 * @Description : 发送消息
 * @Author : ZG
 * @Date: 2024-08-02 10:57
 */
public class SendMessage {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket对象
        DatagramSocket datagramSocket = new DatagramSocket(9999);
        //打包数据
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请输入内容!");
            String nextLine = scanner.nextLine();
            if ("886".equals(nextLine)) {
                break;
            }else {
                byte[] bytes = nextLine.getBytes();
                InetAddress address = InetAddress.getByName("127.0.0.1");
                int port = 8888;
                DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, address, port);
                //发送数据
                datagramSocket.send(datagramPacket);
            }
        }
        //释放资源
        datagramSocket.close();
    }
}
/**
 * @ClassName ReceiveMessage
 * @Description : 接收消息方
 * @Author : ZG
 * @Date: 2024-08-02 11:04
 */
public class ReceiveMessage {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket对象
        DatagramSocket datagramSocket = new DatagramSocket(8888);
        //接收数据包
        byte[] bytes = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
        //解析数据包
        while (true) {
            datagramSocket.receive(datagramPacket);
            byte[] data = datagramPacket.getData();
            int length = datagramPacket.getLength();
            int port = datagramPacket.getPort();
            String message = new String(data, 0, length);
            System.out.println("接收到来自" + port + "端口的数据:\r\n" + message);
        }

    }
}

组播

/**
 * @ClassName SendMessage
 * @Description : 组播发送消息
 * @Author : ZG
 * @Date: 2024-08-02 10:57
 */
public class SendMessage {
    public static void main(String[] args) throws IOException {
        //MulticastSocket
        MulticastSocket ms = new MulticastSocket(9999);
        //打包数据
        byte[] bytes = "你好啊!".getBytes();
        InetAddress address = InetAddress.getByName("224.0.0.1");
        int port = 10000;
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
        //发送数据
        ms.send(dp);
        //释放资源
        ms.close();
    }
}
/**
 * @ClassName ReceiveMessage
 * @Description : 组播接收消息1
 * @Author : ZG
 * @Date: 2024-08-02 11:04
 */
public class ReceiveMessage01 {
    public static void main(String[] args) throws IOException {
        //创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket(10000);
        //将当前本机,添加到224.0.0.1这一组中
        InetAddress address = InetAddress.getByName("224.0.0.1");
        ms.joinGroup(address);
        //接收数据包
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
        //解析数据包
        ms.receive(dp);
        byte[] data = dp.getData();
        int length = dp.getLength();
        InetAddress inetAddress = dp.getAddress();
        String ip = inetAddress.getHostAddress();
        String name = inetAddress.getHostName();
        int port = dp.getPort();
        String message = new String(data, 0, length);
        System.out.println("接收到来自IP地址为:" + ip + "\r\n主机名为:" + name + "机器\r\n端口号为:" + port + "\r\n数据为:" + message);
        //释放资源
        ms.close();
    }
}
/**
 * @ClassName ReceiveMessage
 * @Description : 组播接收消息1
 * @Author : ZG
 * @Date: 2024-08-02 11:04
 */
public class ReceiveMessage02 {
    public static void main(String[] args) throws IOException {
        //创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket(10000);
        //将当前本机,添加到224.0.0.1这一组中
        InetAddress address = InetAddress.getByName("224.0.0.1");
        ms.joinGroup(address);
        //接收数据包
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
        //解析数据包
        ms.receive(dp);
        byte[] data = dp.getData();
        int length = dp.getLength();
        InetAddress inetAddress = dp.getAddress();
        String ip = inetAddress.getHostAddress();
        String name = inetAddress.getHostName();
        int port = dp.getPort();
        String message = new String(data, 0, length);
        System.out.println("接收到来自IP地址为:" + ip + "\r\n主机名为:" + name + "机器\r\n端口号为:" + port + "\r\n数据为:" + message);
        //释放资源
        ms.close();
    }
}
/**
 * @ClassName ReceiveMessage
 * @Description : 组播接收消息3
 * @Author : ZG
 * @Date: 2024-08-02 11:04
 */
public class ReceiveMessage03 {
    public static void main(String[] args) throws IOException {
        //创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket(10000);
        //将当前本机,添加到224.0.0.1这一组中
        InetAddress address = InetAddress.getByName("224.0.0.1");
        ms.joinGroup(address);
        //接收数据包
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
        //解析数据包
        ms.receive(dp);
        byte[] data = dp.getData();
        int length = dp.getLength();
        InetAddress inetAddress = dp.getAddress();
        String ip = inetAddress.getHostAddress();
        String name = inetAddress.getHostName();
        int port = dp.getPort();
        String message = new String(data, 0, length);
        System.out.println("接收到来自IP地址为:" + ip + "\r\n主机名为:" + name + "机器\r\n端口号为:" + port + "\r\n数据为:" + message);
        //释放资源
        ms.close();
    }
}

广播

/**
 * @ClassName SendMessage
 * @Description : 广播发送消息
 * @Author : ZG
 * @Date: 2024-08-02 10:57
 */
public class SendMessage {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket对象
        DatagramSocket ds = new DatagramSocket(9999);
        //打包数据
        byte[] bytes = "你好啊!!!".getBytes();
        InetAddress address = InetAddress.getByName("255.255.255.255");
        int port = 8888;
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
        //发送数据
        ds.send(dp);
        //释放资源
        ds.close();
    }
}
/**
 * @ClassName ReceiveMessage
 * @Description : 广播接收消息
 * @Author : ZG
 * @Date: 2024-08-02 11:04
 */
public class ReceiveMessage {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket对象
        DatagramSocket ds = new DatagramSocket(8888);
        //接收数据包
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
        //解析数据包
        ds.receive(dp);
        byte[] data = dp.getData();
        int length = dp.getLength();
        InetAddress inetAddress = dp.getAddress();
        String ip = inetAddress.getHostAddress();
        String name = inetAddress.getHostName();
        int port = dp.getPort();
        String message = new String(data, 0, length);
        System.out.println("接收到来自IP地址为:" + ip + "\r\n主机名为:" + name + "机器\r\n端口号为:" + port + "\r\n数据为:" + message);
        //释放资源
        ds.close();

    }
}

TCP协议

  • TCP通信协议是一种可靠的网络协议,它在通信的两端建立一个Socket对象
  • 通信之前要保证连接已经建立
  • 通过Socket产生IO流来进行通信
/**
 * @ClassName SendMessage
 * @Description : 发送消息
 * @Author : ZG
 * @Date: 2024-08-02 10:57
 */
public class SendMessage {
    public static void main(String[] args) throws IOException {
        //TCP协议发送数据
        //创建Socket对象,在创建对象的同时会连接服务端,连接不上的话会报错
        Socket socket = new Socket("127.0.0.1", 8888);
        //从连接通道中获取输出流
        OutputStream os = socket.getOutputStream();
        //解决中文乱码,使用转换流
        OutputStreamWriter ow = new OutputStreamWriter(os);
        //写出数据
        ow.write("你好啊!");
        //释放资源
        ow.close();
        socket.close();
    }
}
/**
 * @ClassName ReceiveMessage
 * @Description : 接收消息方
 * @Author : ZG
 * @Date: 2024-08-02 11:04
 */
public class ReceiveMessage {
    public static void main(String[] args) throws IOException {
        //创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(8888);
        //监听客户端连接
        Socket accept = serverSocket.accept();
        //从连接通道中获取输入流读取数据
        InputStream is = accept.getInputStream();
        //解决中文乱码,使用转换流
        InputStreamReader ir = new InputStreamReader(is);
        int read;
        while ((read = ir.read()) != -1) {
            System.out.print((char) read);
        }
        //释放资源
        ir.close();
        serverSocket.close();
    }
}

三次握手

确保连接建立

  1. 客户端向服务端发送连接请求,等待服务器确认
  2. 服务端向客户端返回一个响应,告诉客户端收到了请求
  3. 客户端再次向服务端再次发送确认消息,连接建立

四次挥手

确保连接断开,数据处理完毕

  1. 客户端向服务端发送取消请求

  2. 服务端向客户端返回一个响应,表示收到了客户端的取消请求

  3. 服务端向客户端发出确认取消信息

  4. 客户端向服务端再次发送确认消息,连接取消