Java高级编程—网络编程(完整详解,包括UDP通信方式、TCP通信方式、TCP三次握手、TCP四次挥手,附有代码+案列)

news2024/9/21 2:41:07

文章目录

  • 二十九.网络编程
    • 29.1 概述
    • 29.2 InetAddress
    • 29.3 UDP通信
      • 29.3.1 UDP通信发送数据
      • 29.3.2 UDP通信接收数据
      • 29.3.3 Test
    • 29.4 UDP的三种通信方式
      • 29.4.1 单播
      • 29.4.2 组播
      • 29.4.3 广播
    • 29.5 TCP通信
    • 29.6 TCP通信三次握手
    • 29.7 TCP通信四次挥手
    • 29.8 Test
      • 29.8.1 多次发送

二十九.网络编程

29.1 概述

网络编程三要素

  • IP:设备在网络中的地址,是唯一标识的
  • 端口号:应用程序在设备中的唯一标识(0-65535)
  • 协议:数据在网络中传输的规则(UDP、TCP、http…)

29.2 InetAddress

static InetAddress getByName(String host) 
确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址

String getHostName()              获取此IP地址的主机名
String getHostAddress()           返回文本显示中的IP地址字符串

(遇见异常直接抛,默认采用alt+enter提示的第一种方式处理异常)

import java.net.InetAddress;
import java.net.UnknownHostException;

public class Test01 {
    public static void main(String[] args) throws UnknownHostException {

        InetAddress mykwh = InetAddress.getByName("mykwh");
        System.out.println(mykwh);//mykwh/169.254.146.8

        String hostAddress = mykwh.getHostAddress();
        System.out.println(hostAddress);//169.254.146.8

        String hostName = mykwh.getHostName();
        System.out.println(hostName);//mykwh
    }
}

29.3 UDP通信

29.3.1 UDP通信发送数据

  • 创建发送端的DatagramSocket对象
  • 数据打包(DatagramPacket)
  • 发送数据
  • 释放资源

(遇见异常直接抛,默认采用alt+enter提示的第一种方式处理异常)

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

public class Test02 {
 public static void main(String[] args) throws IOException {

        // 1.创建发送端的DatagramSocket对象(相当于快递公司)
        //绑定端口,以后我们就是通过这个端口往外发送
        //空参:所有可用的端口中随机一个进行使用
        //有参:指定端口号进行绑定
        DatagramSocket ds = new DatagramSocket();

        //2. 数据打包(DatagramPacket)
        String str = "你好";
        //2.1 把字符串变成字节数组
        byte[] bytes = str.getBytes();
       //向127.0.0.1的设备发送
        InetAddress address = InetAddress.getByName("127.0.0.1");
        //2.2发送到某目的地的端口号
        int port = 10011;
        //2.3 打包发送
        DatagramPacket dp = new      DatagramPacket(bytes,bytes.length,address,port);

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

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

    }
}

29.3.2 UDP通信接收数据

  • 创建接收端的DatagramSocket对象
  • 接收打包好的数据
  • 解析数据包
  • 释放资源

注意:必须先执行29.3.1中的发送数据代码,再执行接收数据代码

(遇见异常直接抛,默认采用alt+enter提示的第一种方式处理异常)

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

public class ReceiveMessTest {
 public static void main(String[] args) throws IOException {

        // 1.创建接收端的DatagramSocket对象,
        // 参数与发送端的端口号保持一致
        DatagramSocket ds = new DatagramSocket(10011);

        // 2.接收数据包
        // 2.1 新建数组用来接收数据(相当于用一个新的箱子来装数据)
        byte[] bytes = new byte[1024];
        // 2.2用bytes接收收据,并且用bytes所有的空间来接收
       DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
   
       // 2.3 接收
        //receive方法是阻塞的
        //程序执行到这一步的时候,会在这里死等
        //等发送端发送消息
        ds.receive(dp);

        // 3.解析数据包
        // 3.1 将数据包(即 bytes数组)里的数据解析到数组data
        byte[] data = dp.getData();
        //获取当前接收到多少字节数据
        int length = dp.getLength();
        // 获取发送设备的ip
        InetAddress address = dp.getAddress();
        // 获取发送设备的端口号
        int port = dp.getPort();

        System.out.println("接收的数据是:"+ new String(data,0,length));
        System.out.println("接收数据是从"+address+"这个设备的"+port+"端口号发出的");

    }
}

29.3.3 Test

UDP发送:输入ending时结束发送

UDP接收:因不知发送端何时停止发送,故采用死循环接收

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

public class SendMessTest {
 public static void main(String[] args) throws IOException {

        // 1.创建发送端对象
        DatagramSocket ds = new DatagramSocket();

        // 2.打包数据
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入要发送的数据:");
            String str = sc.nextLine();
            if("ending".equals(str)){
                break;
            }
            byte[] bytes = str.getBytes();
            InetAddress address = InetAddress.getByName("127.0.0.1");
            int port = 10011;
            DatagramPacket dp = new  DatagramPacket(bytes,bytes.length,address,port);

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

        // 4.释放资源
        ds.close();
    }
}
=====================================================
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiveMessTest {
 public static void main(String[] args) throws IOException {

        // 1.创建接收端的DatagramSocket对象,
        DatagramSocket ds = new DatagramSocket(10011);

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

        while (true) {
            // 3.接收数据
            ds.receive(dp);

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

            // 5.打印数据
           System.out.println("ip为:"+ip+",主机为:"+name+",端口号为:"+port+",的设备发送了"+ new String(data,0,len));
        }

    }
}

29.4 UDP的三种通信方式

单薄、组播、广播

29.4.1 单播

//单播:创建DatagramSocket对象形式
DatagramSocket ds = new DatagramSocket();

29.4.2 组播

组播地址:224.0.0.0 ~ 239.255.255.255

其中:224.0.0.0 ~ 224.0.0.255为预留的组播地址,自己用预留的组播地址。

创建MulticastSocket接收端对象
MulticastSocket ms = new MulticastSocket(10011);
public class SendMessTest {
 public static void main(String[] args) throws IOException {
        // 组播发送端

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

        //2. 数据打包(DatagramPacket)
        // 2.1要打包的数据,即发送的剧数据
        String str = "追风赶月莫停留,平芜尽处是春山";
        // 2.2 将发送的字符串数据变成字符数组
        byte[] bytes = str.getBytes();
        // 2.3 向这个地址的内的设备发送
        InetAddress address = InetAddress.getByName("224.0.0.6");
        //2.4向10011端口发送
        int port = 10011;
        // 2.5 打包数据,
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);

        // 3.调用MulticastSocket发送数据方法发送数据
        ms.send(dp);

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

    }
}
======================================================
  public class ReceiveMessTest01 {
    public static void main(String[] args) throws IOException {
        // 组播接收端1

        //1. 创建MulticastSocket接收端对象
        MulticastSocket ms = new MulticastSocket(10011);

        // 2. 将将当前本机,添加到224.0.0.6的这一组当中
       InetAddress address = InetAddress.getByName("224.0.0.6");
        ms.joinGroup(address);

        // 3.接收数据包
        // 3.1 新建数组用来接收数据(相当于用一个新的箱子来装数据)
        byte[] bytes = new byte[1024];
        // 3.2用bytes接收收据,并且用bytes所有的空间来接收
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length);

        //4. 接收数据
        ms.receive(dp);

        // 5.解析数据
        // 将数据包(即 bytes数组)里的数据解析到数组data
        byte[] data = dp.getData();
        //获取当前接收到多少字节数据
        int len = dp.getLength();
        // 获取发送设备的端口号
        int port = dp.getPort();
        // 获取发送设备的ip和名字
        String ip = dp.getAddress().getHostAddress();
        String name = dp.getAddress().getHostName();

        System.out.println("ip为:" + ip +",主机名为:" + name + "的人,发送了数据:" + new String(data,0,len));

        //6. 释放资源
        ms.close();
    }
}
======================================================
  public class ReceiveMessTest02 {
    public static void main(String[] args) throws IOException {

        // 组播接收端2

        //1. 创建MulticastSocket接收端对象
        MulticastSocket ms = new MulticastSocket(10011);

        // 2. 将将当前本机,添加到224.0.0.6的这一组当中
       InetAddress address = InetAddress.getByName("224.0.0.6");
        ms.joinGroup(address);

        // 3.接收数据包
        // 3.1 新建数组用来接收数据(相当于用一个新的箱子来装数据)
        byte[] bytes = new byte[1024];
        // 3.2用bytes接收收据,并且用bytes所有的空间来接收
       DatagramPacket dp = new DatagramPacket(bytes,bytes.length);

        //4. 接收数据
        ms.receive(dp);

        // 5.解析数据
        // 将数据包(即 bytes数组)里的数据解析到数组data
        byte[] data = dp.getData();
        //获取当前接收到多少字节数据
        int len = dp.getLength();
        // 获取发送设备的端口号
        int port = dp.getPort();
        // 获取发送设备的ip和名字
        String ip = dp.getAddress().getHostAddress();
        String name = dp.getAddress().getHostName();

        System.out.println("ip为:" + ip +",主机名为:" + name + "的人,发送了数据:" + new String(data,0,len));

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

29.4.3 广播

广播地址:255.255.255.255

InetAddress address = InetAddress.getByName("127.0.0.1");
将单播发送数据中的这行代码中的 127.0.0.1 改成 255.255.255.255 即可

29.5 TCP通信

  • TCP 通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,但是传输速度慢;面向连接。
  • 通信之前保证连接已经建立
  • 通过Sock产生IO流来进行网络通信
    (图片来自B站Java视频)
    在这里插入图片描述
    在这里插入图片描述

客户端(Socket):

  • 创建客户端的Sock对象(Socket)与指定服务端连接

    Socket ( String host, int port)

  • 获取输出流,写出数据

    OutputStream getOutputStream( )

  • 释放资源

    void close( )

服务器端(ServerSocket):

  • 创建服务器端的Socket对象(ServerSocket)

    ServerSocket(int port)

  • 监听客户端连接,返回一个Socket对象

    Socket accept( )

  • 获取输入流,读取数据,并把数据显示在控制台

    InputStream getInputStream( )

  • 释放资源

    void close( )

运行时要先运行服务端

//客户端,TCP协议,发送数据
public class Client {
 public static void main(String[] args) throws IOException {
        //TCP协议,发送数据

        // 创建Socket对象(客户端)
        //在创建对象的同时会连接服务端的ip:127.0.0.1
        Socket socket = new Socket("127.0.0.1",10011);

        // 连接成功后可从连接通道中获取(字节)输出流
        OutputStream os = socket.getOutputStream();

        // 写出数据,写出是字节数据
        String str = "aa666";
        os.write(str.getBytes());

        // 释放资源
        os.close();
        socket.close();
   //在释放资源时,底层会利用四次挥手协议断开连接,保证连接通道里面的数据已经处理完毕。
    }
}
=======================================================
  //服务器端, TCP协议,接收数据
public class Server {
 public static void main(String[] args) throws IOException {
        //TCP协议,接收数据

        // 1.创建服务端的对象,绑定客户端的端口
        ServerSocket ss = new ServerSocket(10011);

        //2. 监听客户端的连接
        //如果没有客户端连接,会死等
        //如果有客户端连接,会返回客户端的连接对象
        Socket socket = ss.accept();

       // 3.从连接通道中获取(字节)输入流读取数据
        InputStream is = socket.getInputStream();
        // 利用转换流 转成字符转换输入流,保证读取中文不乱码
        InputStreamReader isr  = new InputStreamReader(is);
        //还可可以将用缓冲流包装,用来提升读取效率
        BufferedReader br = new BufferedReader(isr);
   
        // 3.1 定义读取的字节数据
        int b ;
        //3.2 循环读取
        while ((b =is.read()) != -1){
            System.out.println((char) b);
        }

        // 4.释放资源
        // 4.1断开跟客户端的连接
        socket.close();
        // 4.2相当于关闭了服务器
        ss.close();
    }
}

29.6 TCP通信三次握手

(图片来自B站Java视频)
在这里插入图片描述

29.7 TCP通信四次挥手

(图片来自B站Java视频)
在这里插入图片描述

29.8 Test

29.8.1 多次发送

客户端:多次发送数据
服务器:接收多次接收数据,并打印
public class Client {
    public static void main(String[] args) throws IOException {
        //客户端:多次发送数据
        //服务器:接收多次接收数据,并打印

        // 创建Socket对象并连接服务端
        Socket socket = new Socket("127.0.0.1",10011);

        // 获取字节输出流,写出数据
        OutputStream os = socket.getOutputStream();
        Scanner sc = new Scanner(System.in);

        while (true) {
            System.out.println("请输入您要发送的信息:");
            String s = sc.nextLine();
            if ("ending".equals(s)){
                break;
            }
            os.write(s.getBytes());
        }
				//	释放资源
        os.close();
        socket.close();

    }
}
===========================================
  public class Server {
    public static void main(String[] args) throws IOException {
        //客户端:多次发送数据
        //服务器:接收多次接收数据,并打印

        //1.创建服务器端对象绑定10011端口
        ServerSocket ss = new ServerSocket(10011);
        //2.等待客户端来连接
        Socket sock = ss.accept();

        // 读取数据
        // 字节输入流
        InputStream is = sock.getInputStream();
        // 转成字符输入流
        InputStreamReader isr = new InputStreamReader(is);
        //字符缓冲流
        BufferedReader br = new BufferedReader(isr);

        int b ;
        while ((b= isr.read()) != -1){
            System.out.print((char) b);
        }

        // String line;
        // while ((line = br.readLine()) != null){
        //     System.out.println(line);
        // }

        //释放资源
        ss.close();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2115866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java数据结构(九)——选择排序、堆排序

文章目录 选择排序算法介绍代码实现复杂度和稳定性 堆排序算法介绍代码实现复杂度和稳定性 选择排序 算法介绍 选择排序是一种简单直观的排序算法。它的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置…

【二分查找】锦集

二分查找锦集 二分前言1. 二分查找1.1 题目来源1.2 题目描述1.3 代码展示 2. 在排序数组中查找元素的第一个和最后一个位置2.1 题目来源2.2 题目描述2.3 解题分析 3. 搜索插入位置3.1 题目来源3.2 题目描述3.3 解题分析 4. x 的平方根4.1 题目来源4.2 题目描述4.3 解题分析 5. …

Oracle rman 没有0级时1级备份和0级大小一样,可以用来做恢复 resetlogs后也可以

文档说了 full backup 不能 用于后续的level 1,没说level 1没有level 0 是不是level 1就是level 0? 1级备份变0级的原因 及 Enabling Change Tracking生效没有-CSDN博客 这个文档说明1级备份时没有找到0级就是0级备份,可以用来完整恢复的。…

春日美食家:SpringBoot网上订餐系统

1 绪论 1.1 研究背景 随着互联网技术的快速发展,网络时代的到来,网络信息也将会改变当今社会。各行各业在日常企业经营管理等方面也在慢慢的向规范化和网络化趋势汇合[13]。电子商务必将成为未来商务的主流,因此对于餐饮行业来说,…

51单片机的无线病床呼叫系统【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块温湿度传感器模块矩阵按键时钟模块等模块构成。适用于病床呼叫系统、16床位呼叫等相似项目。 可实现基本功能: 1、LCD1602实时显示北京时间、温湿度信息、呼叫床位等信息; 2、DHT11采集病房温湿度信息&…

RTMP播放器延迟最低可以做到多少?

技术背景 RTMP播放器的延迟可以受到多种因素的影响,包括网络状况、推流设置、播放器配置以及CDN分发等。因此,RTMP播放器的延迟并不是一个固定的数值,而是可以在一定范围内变化的。 正常情况下,网上大多看到的,针对R…

【GIS系列】通过Java代码高效实现ArcGIS SDE数据库的数据叠加分析

作者:后端小肥肠 🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案 🍊 有疑问可私信或评论区联系我。 🥑 创作不易未经允许严禁转载。 本文涉及GDAL及GeoTools代码实践&#xff…

计算机毕业设计选题推荐-宠物店管理系统-Java/Python项目实战

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

机器学习(9.2-9.8)pytorch学习(二)

文章目录 摘要Abstract 1 torch 和 torchvision1.1 查看CIFAR10数据集内容1.2 Dataloader的使用 2 神经网络的构建2.1 神经网络的基本骨架2.2 卷积层原理2.2.1 卷积基本原理2.2.2 padding 2.3 构建一个卷积神经网络2.4 池化层2.5 非线性激活2.5.1 RELU的使用2.5.2 Sigmoid的使用…

【开源免费】基于SpringBoot+Vue.J大学生租房平台(JAVA毕业设计)

本文项目编号 T 019 ,文末自助获取源码 \color{red}{T019,文末自助获取源码} T019,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

java基础概念21-权限修饰符、代码块

一、权限修饰符 1-1、作用 权限修饰符,是用来控制一个成员能够被访问的范围的。 可以修饰:成员变量,方法,构造方法,内部类。 1-2、权限修饰符的分类 二、代码块 局部代码块构造代码块静态代码块 2-1、局部代码块 …

【C++ Primer Plus习题】12.5

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream> #include <cstdlib> #in…

Linux-【组管理、权限管理、定时任务调度】

目录 前言 Linux组基本介绍 文件/目录 所有者 查看文件 所有者 修改文件所有者 文件/目录 所在组 修改文件/目录 所在组 其它组 改变用户所在组 权限的基本介绍 rwx权限 rwx作用到文件 rwx作用到目录 修改权限 第一种方式&#xff1a;、-、变更权限 第二种方式…

Java进阶13讲__第11讲

配置文件 日志 1. Properties属性文件 1.1 特点、作用 都只能是键值对键不能重复文件后缀一般是.properties结尾的 1.2 读取 package cn.hdc.oop10.properties;import java.io.FileNotFoundException; import java.io.FileReader; import java.util.Properties; import j…

「iOS」折叠cell

iOS学习 前言简单的折叠cell效果原理 稍作修改总结 前言 在暑期仿写中&#xff0c;3G share项目里我们简单的使用了折叠cell。现在写一篇博客来总结该方法。 简单的折叠cell 效果 先看效果&#xff1a; 原理 将cell的高度设置为一个单元格的高度。创建一个按钮&#xff0…

【C++】作用域指针、智能指针、共享指针、弱指针

十、智能指针、共享指针 从上篇文章 【C】如何用C创建对象&#xff0c;理解作用域、堆栈、内存分配-CSDN博客 中我们知道&#xff0c;你的对象是创建在栈上还是在堆上&#xff0c;最大的区别就是对象的作用域不一样。所以在C中&#xff0c;一旦程序进入另外一个作用域&#xf…

【xinference】(19):在L40设备上通过Xinference框架,快速部署CogVideoX-5b模型,可以生成6秒视频,速度比409D快一点

1&#xff0c;关于Xinference Xorbits Inference (Xinference) 是一个开源平台&#xff0c;用于简化各种 AI 模型的运行和集成。借助 Xinference&#xff0c;您可以使用任何开源 LLM、嵌入模型和多模态模型在云端或本地环境中运行推理&#xff0c;并创建强大的 AI 应用。 htt…

鸿蒙开发笔记_电商严选01_登录页面(静态页面)

由于上班较忙,抽空闲暇时间,快速更新中。。。 效果图 登录页面(静态页面) import CommonConstants from ./CommonConstants;/*** 登录页面*/ // 输入文本框,的自定义样式扩展 // @Extend装饰器表示继承、扩展的意思。这里代表:自定义样式扩展 @Extend(TextInput) functio…

Qt使用小技巧之按钮动态变化

前言 最近写小demo中无意发现的&#xff0c;是想实现当鼠标悬停到按钮上面的时候&#xff0c;按钮实现动态变化&#xff0c;让人知道鼠标经过了按钮&#xff0c;效果如下 hoverDynamicPushButton 正文 首先是将按钮的边框给去掉&#xff0c;然后设置下它的悬停伪状态就行了 格…

linux日常使用命令总结

一、文件复制 在 Linux 中&#xff0c;复制文件是一个常见的操作&#xff0c;通常使用 cp 命令来完成。cp 命令提供了丰富的选项来满足不同的需求。下面是使用 cp 命令复制文件的一些基本用法和示例。 基本用法 cp 命令的基本语法如下&#xff1a; cp [选项] 源文件 目标文…