【JavaEE】网络编程之UDP套接字

目录

1、网络编程基础

2、UDP数据报套接字编程 

2.1.DatagramSocket  API(方法)

2.2、DatagramPacket  API(方法) 

2.3、InetSocketAddress  API  

3、基于UDP socket写一个回显服务器

3.1、服务器端

3.2 、客户端

3.3、完整回显服务器和客户端代码

3.3.1、服务器和客户端代码的执行流程


1、网络编程基础

我们知道网络通信的过程中,发送方将数据从应用层封装到物理层,然后进行发送。接收方在拿到数据之后,将数据从物理层分用到应用层。我们进行网络编程就是将网络上的主机,通过不同的进程,以编程的方式实现网络通信。进行网络编程,我们主要可以操作的就是应用层,其他层都是系统封装好的,我们没有能力去修改。我们要发送一个数据,需要上层协议,调用下层协议,也就是说我们在进行应用层代码编写的时候,需要调用传输层给我们提供的API。这组API我们将其统称为socket api.系统提供的socket api有很多,我们主要了解下面这两组。

由于TCP和UDP这两个协议的差别很大,所以提供的API也存在很大的差异。了解一下这两个协议最基本的特点。

UDP特点TCP特点
无连接有连接
不可靠传输可靠传输
面向数据报面向字节流
全双工全双工
  • 有连接和无连接:有连接可以理解为,通信双方,各自记录了对方信息,表示两台主机在进行通信的时候是否需要记录一下对端的信息。 使用UDP通信的双方,不需要保存对端的相关信息。使用TCP通信的双方,则需要保存对方的相关信息。(使用UDP通信,不需要接受连接,直接投递,就能通信。可以想象一下发短信;使用TCP通信,需要先把链接接收,才能通信。可以想象一下打电话)。
  • 可靠传输与不可靠传输:这里的可靠传输和不可靠传输并不是说安全性的问题,而是说发送端在将数据发送了之后,发送端能不能判断接收端收到信息,如果能够确定接收端收到了信息或者没有接收到消息,这就是可靠传输。不可靠传输就是,发送端将数据发送之后,就不会在管了,至于接收方接收到消息还是没有接收到消息,发送端不关心。
  • 面向字节流和面向数据报:面向字节流就是以字节为传输的基本单位,以流的形式传输数据,可以一次读一个字节,也可以一次读很多字节,读写方式非常灵活。面向数据报就是以一个UDP数据报为基本单位。
  • 全双工和半双工:全双工是一条通信链路,双向通信(就像车道一样)。半双工是一条通信链路,单向通信。

2、UDP数据报套接字编程 

UDP数据报的套接字提供了最主要的两个核心类、一个是DatagramSocket一个是DatagramPacket。

2.1.DatagramSocket  API(方法)

Datagram的意思就是"数据报",Socket,说明这个对象是一个socket对象(相当于对应到系统中一个特殊的文件【socket文件】)。socket文件并非对应到硬盘上的某个数据存储区域,而是对应到网卡这个硬件设备。

我们想要进行网络通信,就需要有socket文件这样的对象,借助这个socket文件对象,才能够间接的操作网卡。这个socket对象就像是一个遥控器。往这个socket对象中写数据,相当于通过网卡发送消息。从这个socket对象中读数据,相当于通过网卡接收消息。

理解:我们在看电视的时候,按遥控器的按钮就相当于给socket对象中写数据,电视机根据接收到的信号,显示对应的画面。电视机显示相应的画面这就相当于网卡对外发送消息。同理从socket对象中读数据我们反着理解 电视机和遥控器的关系。电视机显示一个画面,如果遥控器上有显示屏,那么我们就能看到电视上这个画面对应着遥控器上我们按过的数据。

✨ DatagramSocket类的构造方法:

下面我们提供了两个构造方法一个带参数,一个不带参数,带参数的构造方法中的参数代表的意思就是端口号

方法方法说明
DatagramSocket()创建一个UDP数据报套接字Socket,绑定到本机任意一个随机端口(一般用于客户端)
DatagramSocket(int port)创建一个UDP数据报套接字Socket,绑定本机指定的端口(一般用于服务端 )

第二个带有参数的构造方法可能会被用户端或者服务器都使用,服务器端的socket对象往往都要关联一个具体的端口号。客户端的socket对象则不需要手动指定,系统会自己分配。

✨DatagramSocket方法:

方法方法说明
void receive(DatagramPacket p)从次套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
void send(DatagramPacket p)从此套接字发送数据报(不会阻塞等待,直接发送)
void close()关闭此数据报套接字

2.2、DatagramPacket  API(方法) 

✨DatagramPacket构造方法:

第一个构造方法,不需要设置地址进去,通常用来接收消息;

第二个构造方法,需要显示的设置地址进去,通常要用来发送消息。

方法方法说明
DatagramPacket(byte[ ] buf,int length)构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数则(第一个参数buf)中,接收指定长度(第二个参数length)
DatagramPacket(byte[ ] buf,int offset,int length,SocketAddress  address)构造一个DatagramPacket以用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从0到指定长度(第二个参数length)。address指定目的主机的IP和端口号。

✨ DatagramPacket方法:

方法方法说明
InetAddressgetAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int getPort()从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号
byte[ ] getData()获取数据报中的数据 

构造UDP发送的数据报时,需要传入socketAddress,该对象可以使用InetSocketAddress来创建。

2.3、InetSocketAddress  API  

✨InetSocketAddress(SocketAddress的子类)构造方法:

方法方法说明
InetSocketAddress(InetAddress addr,int port)创建一个Socket地址,包含IP地址和端口号

3、基于UDP socket写一个回显服务器

基于UDP socket写一个最简单的客户端-服务器程序。

3.1、服务器端

回显服务器:客户端发送一个请求,服务端返回一个一摸一样的响应。就比如我们去吃饭,给老板说来一份蛋炒饭,老板没有给你做,他也说了一句老板来一份蛋炒饭。

✨一个服务器,主要做三个核心工作:

  1. 读取请求并解析
  2. 根据请求计算响应(会先服务器就是把这里省略掉了)
  3. 把响应返回到客户端

1️⃣创建一个UDP的socket对象并且指定一个端口号

public class UdpEchoServer {//需要先定义一个socket对象//通过网络通信,必须要使用socket对象private DatagramSocket socket = null;public UdpEchoServer(int port) throws SocketException {//构造socket的同时,指定要关联/绑定的端口。socket = new DatagramSocket(port);}

 我们创建的服务器这个类中构造的socket对象,绑定端口号的时候时会提示要申明异样,这是因为,我们在主方法中创建服务器这个对象并手动指定端口号的时候,我们指定的端口号,可能被其他的进程占用着,这个时候这里的绑定端口号的操作就会出错。(同一个主机上,一个端口,同一时刻只能被一个进程绑定)。

2️⃣启动服务器

        //启动服务器的主逻辑public void start() throws IOException {System.out.println("服务器启动!");while(true){//每次循环,要做三件事情//1.读取请求并解析//构造一个空饭盒DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);//receive 方法会从网卡中读取数据填充到requestPacket对象中。socket.receive(requestPacket);//为了方便处理这个请求,把数据报转换成StringString request = new String(requestPacket.getData(),0, requestPacket.getLength());//2.根据请求计算响应(此处省略这个步骤)//3.把响应结果写回到客户端}}
}

 启动服务器之后,服务器会做三件事情,1读取请求并解析,2.根据请求计算响应,3.把响应结果写回到客户端。服务器不可能只是对一个客户端进行响应,所以这里使用where循环,当服务器对一个客户端服务完成之后,他还需要在对其他客户端的请求做出响应。

❓看到这里有的老铁会想socket对象怎样存储客户端发来的请求数据呢?


  1. 我们在用户态中写一个应用程序,在其中创建了一个socket对象,此时的socket对象在内核中对应了一个PCB(进程控制块),PCB中存在一个文件描述表(记录这个程序打开了那些文件),这个文件描述符表中有一个项,就记录了这个打开的socket文件。socket文件和网卡建立了链接之后,网卡接收到数据之后,对数据报分用到传输层,看到端口号,根据端口号,就找到了对应的进程(也就找到了对应的socket文件)。
  2. 系统内核,会给每个socket文件都分配一定的内存空间分为:1.发送缓冲区,2.接收缓冲区。
  3. 系统会把收到的这个数据拷贝到该socket对应的接收缓冲区中,此时应用程序调用socket.receive方法,就是从该内核中的socket文件的接收缓冲区里把数据拷贝到了receive方法参数中的DatagramPacket对象中。(socket文件的接收缓冲区类似于阻塞队列,receive方法将该缓冲区中内容拷贝到DatagramPacket对象中,就相当于数据出队列)

 补充:

❓❓网卡属于TCP/IP五层协议的那一层?


❗❗如果精确的收,网卡的位置当时应该算是物理层,单网卡时PC与Internet网云连接的通道,因而,IP层也存在并且最重要的也出现在IP层,因此,如果单一的说,网卡在TCP/IP的第二层比较正确。(这也就能解释为什么上述网卡得到数据之后,可以分用到传输层)。

✨理解socket对象调用的receive方法

  • receive这个方法的参数是一个输出型参数。
  • 之前我们在Java中看到的多数方法都是,使用参数作为方法的"输入",使用返回值作为方法的输出。比如我们要调用一个方法找到两数的最小值,这个时候我们就会调用Math类的min方法并输入两个参数,比较完成之后,方法通过return将结果输出。
  • 但是这里的receive方法是传入一个空的packet对象,然后由receive方法内部把参数的这个packet进行填充,等到这个方法执行完毕,packet对象内部也就有了写回的数据。

举例理解:输出型参数,就像是我们去餐厅吃饭,自己拿了一个餐盒,将空餐盒交给打饭阿姨,阿姨把饭打好之后给我们。

画图理解

❗❗❗注意:服务器启动之后,调用start方法,就会立即执行到receive这里,要是此时还没有客户端发来数据,此时receive就会阻塞,一直持续到客户端有请求数据发送过来。

✨理解将请求的数据报转换成为String 

这个操作并非是必须的,只是此处为了后续的代码简单,当客户端发来的数据是"老板来一份蛋炒饭",此时这个数据就会以二进制的形式存在于requestPacket中的字节数组中,把字节数组中的元素拿出来构造成一个String,这个String内容就是"老板来一份蛋炒饭"。

🎉offest:0和requestPacketgetLength()这两个参数的的意义:

requestPacket对象中的byte数组给定的数组长度为4096,但是一个请求数据并没有将这个数组占满,我们构造String时,通过requestPacket.getLength()方法求出请求数据的实际长度。

这两个参数表示的意思为:从byte[ ] 的0下标位置到getLength()这个下标,把这一段用来构造字符串(String)。

3️⃣根据请求计算响应

    //2.根据请求计算响应(此处省略这个步骤)String response = process(request);//这个方法希望是分局请求来计算响应//由于我们写的是回显程序,所以请求是啥,响应就是啥//如果后续写一个别的服务器,不在回显,具有具体的业务,可以修改process方法,//根据需要来重新构造响应private String process(String request) {return request;}

4️⃣把响应写回到客户端

这里有两步操作,1、打包响应,2、发送响应

            //3.把响应结果写回到客户端//和请求的数据报不同,此处构造响应的时候,需要指定这个报要发给谁//根据response字符串,构造一个DatagramPacket对象(响应的数据报)DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,//requestPacket是从客户端这里收来的,getSocketAddress 就会得到客户端的ip和端口requestPacket.getSocketAddress());socket.send(responsePacket);//打印日志System.out.printf("[%s:%d] req: %s, resp: %s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);

我们首先要构造一个响应的数据报,这个数据报中存有根据请求数据计算得出的响应。

  • getBytes()方法的作用是使用idea默认的字符集将此String编码为字节序列,并将结果存储到新的字节数据中。
  • 构造UDP发送的数据报时,需要传入socketAddress,该对象可以使用InetsocketAddress来创建。requestPacket.getSocketAddress()这个操作的作用是,从请求数据报中获取这个响应发送的主机地址。

 


3.2 、客户端

1️⃣创建一个UDP的socket对象

这里我们创建客户端类的时候,如果需要进行网络通信,也需要创建一个socket对象(文件),写这个客户端类的构造方法的时候,我们并不需要显示的关联一个端口号,这并代表客户端没有端口,而是让系统自己分配一个空闲的端口。我们在创建客户端类的时候是需要创建客户端IP和客户端端口的成员变量。因为客户端启动的时候要知道服务器在哪里。

public class UdpEchoClient {private DatagramSocket socket = null;private String serverIP;private int serverPort;//客户端启动,需要知道服务器在哪里public UdpEchoClient(String serverIP,int serverPort) throws SocketException {//对于客户端来说,不需要显示关联端口//这并不代表客户端没有端口,而是让系统自动分配空闲的端口socket = new DatagramSocket();this.serverIP = serverIP;this.serverPort = serverPort;}

2️⃣启动客户端

启动客户端这个方法中存在四个步骤:

  1. 先从控制台,读取一个字符串
  2. 把字符串构造成UDP数据报,并进行发送
  3. 客户端尝试读取服务器返回的响应
  4. 把响应数据转换成字符串(string)显示出来
    public void start() throws IOException {//通过这个客户端可以多次和服务器仅从交互Scanner scanner = new Scanner(System.in);while(true){//1.先从控制台,读取一个字符串System.out.println("-> ");//打印一个提示符,提示用户要输入内容String request = scanner.next();//2.把字符串构造成UDP数据报,并进行发送DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIP),serverPort);socket.send(requestPacket);//3.客户端尝试读取服务器返回的响应DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//4.把响应数据转换成String显示出来String response = new String(responsePacket.getData(),0,responsePacket.getLength());System.out.printf("req: %s,resp: %s\n",request,response);}}

✨理解把字符串构造成UDP数据报。

这里将输入的字符串转换成UDP数据报,需要进行两方面的操作,一方面首先将字符串编码为字节序列,存入新的字节数组中;另一方面需要指定服务器的IP和端口号。

 DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIP),serverPort);
  • getBytes()方法:使用idea默认的字符集将此String编码为字节序列,并将结果存储到新的字节数据中。
  • InetAddress.getBytes(serverIP):设置这个数据报要发送给服务器的主机网络地址(目的主机的IP)。
  • serverPort:表示设置一个端口号(这个端口号表示服务器在执行的时候绑定的那个端口号)

这里对用户输入的字符串进行转换封装成数据报对服务器发送的时候,我们需要设置服务器的主机IP和服务器程序执行所绑定的端口号。

3.3、完整回显服务器和客户端代码

🎉服务器

public class UdpEchoServer {//需要先定义一个socket对象//通过网络通信,必须要使用socket对象private DatagramSocket socket = null;//绑定一个端口,不一定成功,会抛出异常,所以这里需要先申明这个异常//如果某个端口已经被别的进程占用了,此时这里的绑定操作就会出错//同一个主机上,一个端口,同一时刻只能被一个进程绑定public UdpEchoServer(int port) throws SocketException {//构造socket的同时,指定要关联/绑定的端口。socket = new DatagramSocket(port);}//启动服务器的主逻辑public void start() throws IOException {System.out.println("服务器启动!");while(true){//每次循环,要做三件事情//1.读取请求并解析//构造一个空饭盒DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);//receive 方法会从网卡中读取数据填充到requestPacket对象中。socket.receive(requestPacket);//为了方便处理这个请求,把数据报转换成StringString request = new String(requestPacket.getData(),0, requestPacket.getLength());//2.根据请求计算响应(此处省略这个步骤)String response = process(request);//3.把响应结果写回到客户端//和请求的数据报不同,此处构造响应的时候,需要指定这个报要发给谁//根据response字符串,构造一个DatagramPacket对象(响应的数据报)DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,//requestPacket是从客户端这里收来的,getSocketAddress 就会得到客户端的ip和端口requestPacket.getSocketAddress());socket.send(responsePacket);//打印日志System.out.printf("[%s:%d] req: %s, resp: %s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}//这个方法希望是分局请求来计算响应//由于我们写的是回显程序,所以请求是啥,响应就是啥//如果后续写一个别的服务器,不在回显,具有具体的业务,可以修改process方法,//根据需要来重新构造响应private String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer udpEchoServer = new UdpEchoServer(9090);udpEchoServer.start();}
}

 🎉客户端

public class UdpEchoClient {private DatagramSocket socket = null;private String serverIP;private int serverPort;public UdpEchoClient(String serverIP,int serverPort) throws SocketException {//对于客户端来说,不需要显示关联端口//这并不代表客户端没有端口,而是让系统自动分配空闲的端口socket = new DatagramSocket();this.serverIP = serverIP;this.serverPort = serverPort;}public void start() throws IOException {//通过这个客户端可以多次和服务器仅从交互Scanner scanner = new Scanner(System.in);while(true){//1.先从控制台,读取一个字符串System.out.println("-> ");//打印一个提示符,提示用户要输入内容String request = scanner.next();//2.把字符串构造成UDP数据报,并进行发送DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIP),serverPort);socket.send(requestPacket);//3.客户端尝试读取服务器返回的响应DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//4.把响应数据转换成String显示出来String response = new String(responsePacket.getData(),0,responsePacket.getLength());System.out.printf("req: %s,resp: %s\n",request,response);}}public static void main(String[] args) throws IOException {UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);udpEchoClient.start();}
}

3.3.1、服务器和客户端代码的执行流程

 

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

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

相关文章

关于.CSV文件

什么是.CSV文件 csv是逗号分隔值文件格式,一般用WORDPAD或记事本(NOTE),EXCEL打开。csv(逗号分隔值)是一种用来存储数据的纯文本文件,通常都是用于存放电子表格或数据的一种文件格式。 .CSV文件的用途 比如在C语言程序中可以将数据输出到.csv文件中&a…

csv文件的简介

一、csv简介 在项目中看到了导出为.csv各式的文件格式好奇就百度了一下,然后做了一个小demo。 就是用逗号分割为一列。 CSV(逗号分隔值)(Comma-Separated Values,CSV,有时也称为字符分隔值,因…

CSV的简单用法

读文件 import csv with open(test.csv,rb) as myFile: linescsv.reader(myFile) for line in lines: print line 程序输出: [1, 2][3, a][4, b] 写文件 with open(rC:\Users\asus\Desktop\frank.csv,w) as myFile:writer csv.writer(myFile)writer.writero…

解析csv文件

以下内容仅为记录: 第一步:解析csv文件 Testpublic void testcsv() throws Exception {File csv new File("C:\\Users\\hjy\\Desktop\\attendace164_20180312.csv"); // CSV文件路径BufferedReader br null;try{br new BufferedReader(ne…

csv文件介绍与使用

文章目录 CSV文件用法规则创建csv文件读取csv文件 CSV文件 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和…

用Python读取CSV文件的5种方式

典型的数据集stocks.csv: 一个股票的数据集,其实就是常见的表格数据。有股票代码,价格,日期,时间,价格变动和成交量。这个数据集其实就是一个表格数据,有自己的头部和身体。 第一招&#xff1…

Python数据分析基础之CSV文件(5)

选取连续的行 有时,工作表的头部和尾部是我们不想处理的。在很多情况下,工作表头部是标题、作者信息等,尾部是来源、假设、附加说明、注意事项等,我们并不需要处理这些内容。在这时,我们可以用Python来选取CSV文件中连…

Java设计模式—模板方法模式

前言:模板方法模式是模板模式的一个具体实现,它定义了一个抽象类,其中包含一个模板方法和若干个基本方法。其中模板方法定义了算法骨架,而基本方法则由子类来实现。因此,模板方法在定义算法的结构方面提供了支持&#…

一本书让你彻底搞懂安卓系统性能优化(文末送书5本)

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

MySQL redo log、undo log、binlog

MySQL是一个广泛使用的关系型数据库管理系统,它通过一系列的日志来保证数据的一致性和持久性。在MySQL中,有三个重要的日志组件,它们分别是redo log(重做日志)、undo log(回滚日志)和binlog&…

[04-07]最新精选绿色软件每日更新(小熊整理)

[主页浏览] 阿里云浏览器 1.6.5.2025 Beta [网络工具] QQ玫瑰小镇辅助 1.42 [网络工具] 拇指玩安卓游戏安装器 1.07 [网络工具] LOL撸至深(辅助工具) 1.12 [网络工具] 模拟人生3 金钱修改器 [网络工具] 三国群英传7 修改器 [网络工具] 生化危机5修改器 3.1 [网络工具] 生…

华为OD机试真题 Java 实现【高矮个子排队】【2023Q2 100分】,附详细解题思路

一、题目描述 现在有一队小朋友,他们高矮不同,我们以正整数数组表示这一队小朋友的身高,如数组{5,3,1,2,3}。 我们现在希望小朋友排队,以“高”“矮”“高”“矮”顺序排列,每一个“高”位置的小朋友要比相邻的位置高…

python 社区发现算法

转载:这个Python库超级棒啊,包含Louvain 算法、Girvan-Newman 算法等多种社区发现算法,还具有可视化功能_11205354的技术博客_51CTO博客 熟知社区发现算法,你不能错过这个 Python 库。它涵盖 Louvain 算法、Girvan-Newman 算法等…

AI版女网红“半藏森林”上线,服务项目让人意想不到

目前首批网红明星“AI克隆人”已提前上线,主营业务就是打造各种名人版AI聊天机器人,用户付费便可与之聊天。其后台报名参加AI克隆人的网红明星“全网粉丝总数已超过5亿”。该公司这波上线的网红明星AI克隆人,包括此前因“疑似插足他人恋情”&…

SSD源码总结

一、生成默认框 默认框的宽高 默认框的宽高是相对于原图的尺寸计算出来的。 默认框的中心 默认框的中心是相对于特征图的尺寸计算出来的。 二、将真实框分配给默认框 1、区分正负样本 1.1、选取正样本 计算真实框(bboxs)与每个默认框(…

组合数学第五讲

Catalan numbers(卡特兰数) 先通过平衡括号引入卡特兰数序列的概念 1,2,5,14,...,这些数构成了卡特兰数序列,分别代表一共有i个括号时,括号排列构成的合法方案数【从左到右如果所有括号都能依次配对即是合…

Niagara—— Texture Sample 与 Particle Subuv 区别

一,Texture Sample 此节点是最基本的采样节点,依据UV坐标来采样Texture; MipValueMode,设置采样的Mipmap Level; None,根据当前Texture大小和物理缩放,自动选择合适的 Mipmap Level &#xff1b…

将数组中的每一位元素依次循环向后移一位

#include<iostream> using namespace std; int main() {int a[10],i,t,k;for(i0;i<10;i){cin>>a[i];}ka[9];for(i9;i>0;i--){ta[i];a[i]a[i-1];a[i-1]t;}a[0]k;for(i0;i<10;i){cout<<a[i]<<" ";}cout<<endl;return 0; }

定义一个函数,统计具有n个元素的一维数组中大于等于所有元素平均值的元素的个数并返回这个值

#include<iostream> using namespace std; int Count(double a[6],int n) {int average,i,s0,k0;for(i0;i<n;i){ssa[i];}averages/n;for(i0;i<n;i){if(a[i]>average)k;}return k; } int main() {int i,k,n;cout<<"请输入数组的大小n:"<<e…

(附源码)springboot自行车在线租赁管理系统 毕业设计101157

Springboot自行车在线租赁系统 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对自行车租赁等…