Java基础_网络编程

网络编程三要素

  • IP: 设备在网络中的地址,是唯一的标识
  • 端口号: 应用程序在设备中唯一的标识。
  • 协议: 数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。

InetAddress

public class demo {
    public static void main(String[] args) throws UnknownHostException {
        /**
         * static InetAddress getByName(String host)  确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
         * String getHostName()                       获取此IP地址的主机名
         * String getHostAddress()                    返回文本显示中的IP地址字符串
         */

        // 1. 获取InetAddress的对象
        InetAddress address = InetAddress.getByName("cen");
        System.out.println(address);

        String hostName = address.getHostName();
        System.out.println(hostName); // cen

        String hostAddress = address.getHostAddress();
        System.out.println(hostAddress); // 192.168.174.1
    }
}

网络模型

  • OSI参考模型:世界互联协议标准,全球通信规范,单模型过于理想化,未能在因特网上进行广泛推
  • TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。

在这里入图片描述

UDP通信程序

单播

发送数据

public class Demo {
    public static void main(String[] args) throws IOException {
        /**
         * udp发送数据
         */

        // 1. 创建DatagramSocket对象
        // 绑定发送端口
        // 空参: 所有可用端口中随机一个进行使用
        // 有参: 指定端口
        DatagramSocket ds = new DatagramSocket();

        // 2. 打包数据
        String str = "Hello Socket!";
        byte[] bytes = str.getBytes();
        InetAddress address = InetAddress.getByName("127.0.0.1");
        int port = 10086;

        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);

        // 3. 发送数据
        ds.send(dp);

        // 4. 释放资源
        ds.close();

    }
}

接收数据

public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        /**
         * udp接收数据
         */

        // 1. 创建DatagramSocket对象
        // 接收时要绑定端口
        DatagramSocket ds = new DatagramSocket(10086);

        // 2. 接收数据
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
        ds.receive(dp);

        // 3. 解析数据
        byte[] data = dp.getData();
        int len = dp.getLength();
        InetAddress address = dp.getAddress();
        int port = dp.getPort();

        System.out.println("接收到数据: " + new String(data, 0, len));
        System.out.println("该数据是从" + address + "的" + port + "端口发出的");

        // 4. 释放资源
        ds.close();
    }
}

聊天室

// SendDemo
public class SendDemo {
    public static void main(String[] args) throws IOException {
        /**
         * udp循环发送数据, 直到输入886, 停止发送
         */

        DatagramSocket ds = new DatagramSocket();

        Scanner sc = new Scanner(System.in);
        // 循环发送数据
        while(true) {
            String str = sc.nextLine();
            if(str.equals("886")){
                break;
            }
            byte[] bytes = str.getBytes();
            InetAddress address = InetAddress.getByName("127.0.0.1");
            int port = 10086;

            DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);

            ds.send(dp);

        }
        ds.close();

    }
}

// ReceiveDemo
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        /**
         * udp循环接收数据
         */

        DatagramSocket ds = new DatagramSocket(10086);


        while(true) {
            byte[] bytes = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
            ds.receive(dp);

            byte[] data = dp.getData();
            int len = dp.getLength();
            InetAddress address = dp.getAddress();
            int port = dp.getPort();

            System.out.println("接收到数据: " + new String(data, 0, len));
            System.out.println("该数据是从" + address + "的" + port + "端口发出的");
        }
    }
}

组播

  • 组播地址: 224.0.0.0 ~ 239.255.255.255, 其中224.0.0.0 ~ 224.0.0.255为预留的组播地址
// Send
public class SendDemo {
    public static void main(String[] args) throws IOException {
        /**
         * 组播发送
         */

        // 1. 创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket();

        // 2. 创建DatagramPacket对象
        String str = "Hello MultiSocket!";
        byte[] bytes = str.getBytes();
        InetAddress address = InetAddress.getByName("224.0.0.1");
        int port = 10000;

        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);

        // 3. 发送数据
        ms.send(dp);

        // 4. 释放资源
        ms.close();
    }
}

// Receive
public class ReveiveDemo1 {
    public static void main(String[] args) throws IOException {

        MulticastSocket ms = new MulticastSocket(10000);

        // 将当前本机添加到 224.0.0.1
        InetAddress address = InetAddress.getByName("224.0.0.1");
        ms.joinGroup(address);

        // 2. 接收数据
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

        ms.receive(dp);

        // 3. 解析数据
        byte[] data = dp.getData();
        int len = dp.getLength();
        String ip = dp.getAddress().getHostAddress();
        String name = dp.getAddress().getHostName();

        System.out.println("接收到数据: " + new String(data, 0, len));
        System.out.println("该数据是从" + name + "/" + ip + "发出的");

        // 4. 释放资源
        ms.close();
    }
}

广播

将单播程序发送的ip地址改为255.255.255.255就是广播

TCP

TCP通信程序

// Client
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        /**
         * tcp发送数据
         */

        // 1. 创建Socket对象
        // 创建对象的同时会连接服务端, 如果连接不是, 代码会报错
        Socket socket = new Socket("127.0.0.1", 10000);

        // 2. 可以从连接通道中获取输出流
        OutputStream os = socket.getOutputStream();
        // 写出数据
        os.write("Hello TCP连接!".getBytes());

        // 3. 释放资源
        os.close();
        socket.close();
    }
}

// Server
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        /**
         * tcp接收数据
         */
        // 1. 创建ServerSocket对象
        ServerSocket ss = new ServerSocket(10000);

        // 2. 监听客户端的连接
        Socket socket = ss.accept();

        // 3. 从连接通道中获取输入流读取数据
        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        int b;
        while( (b = br.read()) != -1 )
        {
            System.out.print((char) b);
        }

        // 4. 释放资源
        socket.close();
        ss.close();
    }
}
  • 中文乱码: 将字节流通过转换流转换成字符流
  • 提高效率: 转成缓冲流
  • 输入输出流可以无需手动关闭, 因为流是在连接通道里的, 连接断开后, 流也就关闭了
  • 连接关闭时的协议: 四次挥手, 利用四次挥手协议断开连接, 可以保证连接连接通道里的数据已经处理完毕了.

三次握手和四次挥手

  • 三次握手 - 确保连接建立
    1. 客户端向服务器发出连接请求, 等待服务器确认
    2. 服务器向客户端返回一个响应, 告知客户端收到了请求
    3. 客户端向服务器再次发出确认信息, 连接建立
  • 四次挥手 - 确保连接断开, 且数据处理完毕
    1. 客户端向服务器发出取消连接请求
    2. 服务器向客户端返回一个响应, 表示收到客户端取消请求
    3. 服务器将最后的数据处理完毕后, 服务器向客户端发出确认取消信息
    4. 客户端再次发送确认消息, 连接取消

来源

黑马程序员. 阿玮Java零基础

Gitee地址

https://gitee.com/yu-ba-ba-ba/awJava

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y_cen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值