Java学习-21 网络编程

什么是网络编程?

可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)

基本的通信架构

基本的通信架构有2种形式:

CS架构(Client客户端/Server服务端)   

BS架构(Browser浏览器/Server服务端)。

网络通信三要素

IP

01

端口

02

协议

03

设备在网路中的地址,是唯一的标识应用程序在设备中唯一的标识链接和数据在网络中传输的规则

InetAddress

代表IP地址

名称说明
getLocalHost()获取本机IP,会以一个inetAddress的对象返回
getByName(String host)根据ip地址或者域名,返回一个inetAdress对象
getHostName()获取该ip地址对象对应的主机名。
getHostAddress()获取该ip地址对象中的ip地址信息。
isReachable(int timeout)在指定素秒内,判断主机与该ip对应的主机是否能连通

端口

标记正在计算机设备上运行的应用程序的,被规定为一个16位的二进制,范围是0~65535.

分类

周知端口:0~1023,被预先定义的知名应用占用(如:HTTP占用80,FTP占用21)

注册端口:1024~49151,分配给用户进程或某些应用程序

动态端口:49152到65535,之所以称为动态端口,是因为它一般不固定分配某种进程,而是动态分配

注意:我们自己开发的程序一般选择使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错。

开放式网络互联标准:OSI网络参考模型

OSI网络参考模型:全球网络互联标准

TCP/IP网络模型:事实上的国际标准

OSI网络参考模型TCP/IP网络模型各层对应面向操作

应用层

应用层HTTP、FTP、SMTP应用程序需要关注的:浏览器、邮箱、程序员一般在这一层开发
表示层
会话层
传输层传输层UDP、TCP...选择使用的TCP,UDP协议
网络层网络层IP...封装源和目标IP
数据链路层数据链路层+物理层比特流...物理设备中传输
物理层

传输层的2个通信协议
UDP(User Datagram Protocol):用户数据报协议;TCP(Transmission ControlProtocol):传输控制协议。

UDP协议

  • 特点:无连接、不可靠通信。   通信效率高!语音通话视频直播
  • 不事先建立连接,数据按照包发,一包数据包含:自己的IP、程序端口,目的地IP、程序端口和数据(限制在64KB内)等。
  • 发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,故是不可靠的。

TCP协议

  • 特点:面向连接、可靠通信,
  • TCP的最终目的:要保证在不可靠的信道上实现可靠的传输。
  • TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接。

UDP通信

  • 特点:无连接、不可靠通信
  • 事先不建立连接;发送端每次把要发送的数据(限制在64KB内)、接收端IP等信息封装成一个数据包,发出去就不管了。
  • Java提供一个java.net.DatagramSocket类来实现UDP通信。

DatagramSocket:用于创建客户端、服务端

DatagramPacket:创建数据包

客户端实现步骤

  1. 创建DatagramSocket对象(客户端对象) ——> 扔韭菜的人
  2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)——> 韭菜盘子
  3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象 ——> 开始抛出韭菜
  4. 释放资源

 

public class Client {
    public static void main(String[] args) throws Exception {

        // 创建客户端对象
        DatagramSocket socket = new DatagramSocket(7777);

        // 创建数据包对象
        //public DatagramPacket(byte buf[], int offset, int length,
        //                          InetAddress address, int port)
        // 参数一:封装发出去的数据
        // 参数二: 发送出去的数据大小(字节个数)
        // 参数三:服务端的IP地址
        // 参数四:服务器程序的端口
        byte[] bytes = "我是快乐的客户端,我爱你abc".getBytes();
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(),
                6666);

        // 开始正式发送这个数据报的数据出去
        socket.send(packet);
        System.out.println("客户端数据发送完成~~");
        // 释放资源
        socket.close();
    }
}

服务端实现步骤

  1. 创建DatagramSocket对象并指定端口(服务端对象) ——> 接韭菜的人
  2. 创建DatagramPacket对象接收数据(数据包对象) ——> 韭菜盘子
  3. 使用DatagramSocket对象的receive方法,传入DatagramPacket对象 ——> 开始接收韭菜
  4. 释放资源
public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动~~");
        // 创建一个服务器对象
        DatagramSocket socket = new DatagramSocket(6666);

        // 创建一个数据包对象,用于接收数据的
        byte[] buffer = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        // 开始使用数据包来接收客户端发来的数据
        socket.receive(packet);

        //从字节数组中,把接收到的数据直接打印出来
        int len = packet.getLength();
        String rs = new String(buffer, 0, len);
        System.out.println(rs);

        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(packet.getPort());
        socket.close();
    }
}

TCP通信

  • 特点:面向链接、可靠通信
  • 通信双方事先采用“三次握手”方式建立可靠连接,实现端到端的通信,底层能保证数据成功传给服务器。
  • Java提供一个java.net.Socket类来实现TCP通信

TCP通信 ——客户端开发

客户端程序就是通过java.net包下的Socket类实现的

构造器说明
public Socket(String host, int port)根据指定的服务器ip、端口号请求与服务端建立连接,连接通过,就获得了客户端socket
方法说明
public outputStream getOutputStream()获取字节输出流对象
public InputStream getInputStream()获得字节输入流对象
public class Client {
    public static void main(String[] args) throws Exception {
        // 创建Socket对象,并同时请求与服务程序的连接
        Socket socket = new Socket("127.0.0.1", 8888);

        // 从socket通信管道中得到一个字节输出流,用来发送数据给服务器
        OutputStream os = socket.getOutputStream();

        // 把低级的字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);

        // 开始写数据
        dos.writeUTF("约会吗?");

        dos.close();
        socket.close();
    }
}

客户端实现步骤

  1. 创建客户端的Socket对象,请求与服务端的连接
  2. 使用socket对象调用getOutputStream()方法得到字节输出流
  3. 使用字节输出流完成数据的发送
  4. 释放资源:关闭管道close  

 

TCP通信——服务端程序的开发

服务端是通过java.net包下的ServerSocket类来实现的

ServerSocket

构造器说明
public ServerSocket(int port)为服务端程序注册端口
方法说明
public Socket accept()阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象
public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务器启动~~");
        // 创建ServerSocket对象 接收客户端数据
        ServerSocket serverSocket = new ServerSocket(8888);

        // ServerSocket对象accept方法 等待客户端发起请求 也是socket
       Socket socket = serverSocket.accept();

       // 从Socket管道中得到一个字节流输入
        InputStream is = socket.getInputStream();
        DataInputStream dis = new DataInputStream(is);

        String str = dis.readUTF();
        System.out.println(str);

        // 获取IP地址
        System.out.println(socket.getRemoteSocketAddress());
        dis.close();
        serverSocket.close();
    }
}

服务端实现步骤

  1. 创建ServerSocket对象,注册服务端端口(与客户端一致)
  2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
  3. 通过Socket对象调用getInputStream()方法得到字节输入流,完成数据的接收
  4. 释放资源:关闭socket管道

使用TCP通信实现:多发多收消息

客户端使用死循环,让用户不断输入消息

服务端也使用死循环,控制服务端收完消息,继续等待下一个消息

public class Client {
    public static void main(String[] args) throws Exception {
        // 创建Socket对象,并同时请求与服务程序的连接
        Socket socket = new Socket("127.0.0.1", 8888);
        // 从socket通信管道中得到一个字节输出流,用来发送数据给服务器
        OutputStream os = socket.getOutputStream();
        // 把低级的字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);

        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String str = sc.next();
            // 开始写数据
            if("exit".equals(str)){
                System.out.println("欢迎下次再来,退出成功~");
                dos.close();
                socket.close();
                break;
            }
            dos.writeUTF(str);
        }
    }
}

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务器启动~~");
        // 创建ServerSocket对象 接收客户端数据
        ServerSocket serverSocket = new ServerSocket(8888);

        while (true) {
            // ServerSocket对象accept方法 等待客户端发起请求 也是socket
            Socket socket = serverSocket.accept();
            // 从Socket管道中得到一个字节流输入
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            try {
                String str = dis.readUTF();
                System.out.println(str);
            } catch (Exception e) {
                System.out.println(socket.getRemoteSocketAddress() + "离线了");
                dis.close();
                serverSocket.close();
                break;
            }
            //System.out.println(socket.getRemoteSocketAddress());
        }
    }
}

TCP服务端与多个客户端通信(启动多线程)

public class Client {
    public static void main(String[] args) throws Exception {
        // 创建Socket对象,并同时请求与服务程序的连接
        Socket socket = new Socket("127.0.0.1", 8888);
        // 从socket通信管道中得到一个字节输出流,用来发送数据给服务器
        OutputStream os = socket.getOutputStream();
        // 把低级的字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);

        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String str = sc.next();
            // 开始写数据
            if("exit".equals(str)){
                System.out.println("欢迎下次再来,退出成功~");
                dos.close();
                socket.close();
                break;
            }
            dos.writeUTF(str);
        }
    }
}

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务器启动~~");
        // 创建ServerSocket对象 接收客户端数据
        ServerSocket serverSocket = new ServerSocket(8888);

        while (true) {
            // ServerSocket对象accept方法 等待客户端发起请求 也是socket
            Socket socket = serverSocket.accept();
            // 创建多线程处理
            new ServerReaderThread(socket).start();
        }
    }
}

public class ServerReaderThread extends Thread {
    private final Socket socket;
    public ServerReaderThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            String name = Thread.currentThread().getName();
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                try {
                    String str = dis.readUTF();
                    System.out.println(str);
                } catch (Exception e) {
                    System.out.println(socket.getRemoteSocketAddress() + "下线了");
                    socket.close();
                    dis.close();
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ATCoder Beginnner Contest 341 A~G

A.Print 341&#xff08;模拟&#xff09; 题意&#xff1a; 给定一个正整数 N N N&#xff0c;输出由 N N N个0和 ( N 1 ) (N1) (N1)个1交替组成的字符串。 分析&#xff1a; 按题意模拟即可 代码&#xff1a; #include<bits/stdc.h>using namespace std;int mai…

TestNG与ExtentReport单元测试导出报告文档

TestNG与ExtentReport集成 目录 1 通过实现ITestListener的方法添加Reporter log 1.1 MyTestListener设置 1.2 输出结果 2 TestNG与ExtentReporter集成 2.1 项目结构 2.2 MyExtentReportListener设置 2.3 单多Suite、Test组合测试 2.3.1 单Suite单Test 2.3…

十七、多线程

一、目标 理解线程的概念掌握线程的创建和启动了解线程的状态掌握线程调度的常用方法掌握线程的同步理解线程安全的类型 二、进程、线程、多线程的理解 进程&#xff1a;应用程序的执行实例、有独立的内存空间和系统资源 线程&#xff1a;CPU调度和分派的基本单位、进程中执行运…

2023数据要素市场十大关键词

2023数据要素市场十大关键词 导读 2023年即将过去。一年之前&#xff0c;《中共中央国务院关于构建数据基础制度更好发挥数据要素作用的意见》&#xff08;简称“数据二十条”&#xff09;正式对外发布&#xff0c;为数据要素市场的建设举旗定向。 图片 2023年是“数据二十条…

抖店开通后的这些基础搭建,你了解吗?今天一文详解!

大家好&#xff0c;我是电商小布。 很多小伙伴在我们店铺开通后&#xff0c;接下来就会进行选品上架等工作。 但其实&#xff0c;在店铺刚开通时&#xff0c;小店的基础设置是并不完善的。 比如说&#xff1a;平台默认店铺是全地区包邮的。 想要让小店顺利运转&#xff0c;…

徐晓艺被波兰前总统布罗尼斯瓦夫·科莫罗夫斯基接见

2024年1月19日,科莫罗夫斯基阁下总统俱乐部全球主席总统有话说共同主席波兰第五任总统布罗尼斯瓦夫科莫罗夫斯基 Former President of Poland莅临北京丰台宴 科莫罗夫斯基总统阁下一生充满传奇,他的外交成就也颇为杰出,其中一项就是中波关系。他说:“我作为总统在2011年对华访…

vue3 toRefs之后的变量修改方法

上效果 修改值需要带上解构之前的对象名obj&#xff0c; changeName:()>{ // toRefs 解决后变量修改值方法&#xff1a; 解构前变量.字段新值 obj.name FEIFEI; } } 案例源码 <!DOCTYPE html> <html> <head><me…

【Azure 架构师学习笔记】- Azure Databricks (10) -- UC 使用

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (9) – UC权限 在前面的文章&#xff1a;【Azure 架构师学习笔记】- Azure Databricks (6) - 配置Unity Catalog中演示了如何配置一个UC。 本文…

【Vuforia+Unity】AR04-地面、桌面平面识别功能

不论你是否曾有过相关经验&#xff0c;只要跟随本文的步骤&#xff0c;你就可以成功地创建你自己的AR应用。 官方教程Ground Plane in Unity | Vuforia Library 这个功能很棒&#xff0c;但是要求也很不友好&#xff0c;只能支持部分移动设备&#xff0c;具体清单如下&#xf…

书生·浦语大模型实战营第六节课作业

基础作业 python run.py --datasets ceval_gen --hf-path /root/model/Shanghai_AI_Laboratory/internlm2-chat-7b/ --tokenizer-path /root/model/Shanghai_AI_Laboratory/internlm2-chat-7b/ --tokenizer-kwargs padding_sideleft truncationleft trust_remote_codeTrue --m…

栽花-第15届蓝桥第4次STEMA测评Scratch真题精选

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第169讲。 第15届蓝桥杯第4次STEMA测评已于2024年1月28日落下帷幕&#xff0c;编程题一共有6题&#xff0c;分别如下&a…

HarmonyOS—添加/删除Module

Module是应用/服务的基本功能单元&#xff0c;包含了源代码、资源文件、第三方库及应用/服务配置文件&#xff0c;每一个Module都可以独立进行编译和运行。一个HarmonyOS应用/服务通常会包含一个或多个Module&#xff0c;因此&#xff0c;可以在工程中创建多个Module&#xff0…

什么是web组态?

一、web组态的定义和背景 在深入探讨之前&#xff0c;我们先回顾一下“组态”的定义。在工业自动化领域&#xff0c;组态软件是用于创建监控和数据采集&#xff08;SCADA&#xff09;系统的工具&#xff0c;它允许工程师构建图形界面&#xff0c;实现与各种设备和机器的数据交互…

性能全面提升!探索ONLYOFFICE最新8.0版:更快速、更强大,PDF表单编辑轻松搞定!

文章目录 PDF表单功能表单模板 屏幕朗读器功能EXCEL新增功能单变量求解图表向导数字排序 PPT 新增功能新增语言区域设置和优化插件界面 ONLYOFFICE 是由 Ascensio System SIA 推出的一款功能强大的办公套件&#xff0c;其中提供了适用于文本文档、表格以及演示文稿的在线编辑软…

通过盲注脚本复习sqllabs第46关order by 注入

在MySQL支持使用ORDER BY语句对查询结果集进行排序处理&#xff0c;使用ORDER BY语句不仅支持对单列数据的排序&#xff0c;还支持对数据表中多列数据的排序。语法格式如下 select * from 表名 order by 列名(或者数字) asc&#xff1b;升序(默认升序) select * from 表名 or…

win10系统secoclient连接服务器时,报错与对方建立连接超时,配置错误或网络故障

故障原因 secoclient连接时出现超时的故障&#xff0c;之前还是正常的&#xff0c;可能与最近的系统更新有关 解决方案 找到设备管理 找到网络适配器下的SVN adapter V1.0 禁用该适配器 进入C:\Windows\System32\drivers 找到SVNDrv.sys 把这个文件删除或者重命名一下…

解决docker中运行的jar包连不上前端程序

目录 检查端口映射 查看容器的 IP 地址 检查容器网络设置 防火墙和网络策略 前端程序配置 跨域资源共享 (CORS) 日志查看 连接问题通常涉及到网络配置和端口映射。确保你在 Docker 中运行的 JAR 包可以被前端程序访问&#xff0c;可以采取以下步骤来解决问题&#xff1a…

信钰证券|A股IPO失意后转道南下,内地企业成港股上市“主力军”

内地企业已经成为赴港上市的主力。 Wind数据闪现&#xff0c;本年以来到2月21日&#xff0c;在港股初度聆讯的19家公司中&#xff0c;作业地址在内地的有18家&#xff0c;只要一家作业地址在我国香港。此外&#xff0c;本年在港股上市的5家企业&#xff0c;首要作业地址也均在…

【计组】计算机体系结构

1.CPU的组成 1.1 运算器 算术逻辑单元&#xff08;ALU&#xff09;&#xff1a;逻辑运算累加寄存器&#xff08;AC&#xff09;&#xff1a;存储算数运算结果&#xff08;包括中间结果&#xff09;数据缓冲寄存器&#xff08;DR&#xff09;&#xff1a;临时存储从内存中读取…

星河做市基金会全球DAO社区启动,为数字货币市场注入新活力

2024年的数字货币市场即将迎来一次重要的历史性时刻 — 比特币减半&#xff0c;这四年一次的事件将成为全球数字资产市场的焦点&#xff0c;预示着新一轮的牛市浪潮即将到来。在这个关键时刻&#xff0c;星河做市基金会展现出其作为区块链行业领先市值管理公司的独特魅力。 GA…