JavaEE - 网络编程之回显服务器

目录

一.什么是回显服务器?

二.UDP是什么?

1.TCP 是有链接的, UDP 是无连接的

2.TCP是可靠传输的,UDP是不可靠传输的

3.TCP是面向字节流的,UDP是面向数据报

4.TCP和UDP是全双工的

三.UDP的 socket api 

四. 具体代码实现

1.服务器部分

2.客户端部分 

 3. 具体的流程到底是个啥?

4.执行结果


一.什么是回显服务器?

回显服务器是网络编程中一个简单的代码示例,回显的意思就是客户端发给服务器什么东西,服务器就返回给客户端什么东西。此处我们使用UDP来进行编写回显服务器。

既然此处我们要使用UDP来编写回显服务器,那么我们就有必要去了解UDP是什么?

二.UDP是什么?

UDP是五层网络模型中传输层的协议。其实这个传输层的协议有两个,一个是TCP,另一个就是UDP。两者的区别如下:

1.TCP 是有链接的, UDP 是无连接的

此处链接的本质就是建立连接的双方,各自保存对方的信息.

TCP要想通信,就需要先建立连接(保存对方信息),然后才能后续通信。

如果A 想和 B 建立连接,但是 B 拒绝了!通信就无法完成!

UDP要想建立链接,就直接发送数据即可,不需要征得对方的同意,UDP自身也不会保存对方信息。但是应用程序层面会知道。

2.TCP是可靠传输的,UDP是不可靠传输的

什么是可靠?究竟什么样子才算可靠?

其实这个可靠是一个模糊的概念,比如我是一个非常厉害的老中医,但是假如有病人问我这个病能不能百分百治好的时候,我只能说:“我尽力治好~~~” 。  此时我是可靠的呢还是不可靠的呢?其实应该是可靠的,因为此时我的医术很精明,已经很接近有百分百的把握了。

在网络上进行通信,A - >B 的过程中,这个消息是不可能 100% 送达的

TCP内置了可靠传输机制,发送失败的时候会采取一定的措施(比如尝试重传之类的)

UDP就没有内置可靠传输机制!

但是我们思考,为什么UDP不搞一个可靠传输呢?

因为可靠传输是要付出代价的: 机制更复杂    传输效率更低~

3.TCP是面向字节流的,UDP是面向数据报

TCP是以字节为单位来进行传输的.

UDP是以数据报为单位来进行传输的.

4.TCP和UDP是全双工的

也就是两者都允许双向通信,客户端可以发送请求给服务器,服务器也可以发送相应给客户端。

三.UDP的 socket api 

socket本质上就是一个特殊的文件,把“网卡”抽象成了文件

往socket 文件中写数据,就相当于通过网卡发送数据

往socket 文件中读数据,就相当于通过网卡接收数据

在Java中,UDP的API主要有两种:

DatagramSocket  和  DatagramPacket

其实这两个对象,可以这样理解:DatagramSocket  就相当于一个网关文件, 而 DatagramPacket就相当于穿梭在这个网关文件中的数据报。

也就是客户端要发送这个数据报给服务器 ,  服务器要把相应再以数据报的形式发给客户端。

四. 具体代码实现

1.服务器部分

package net;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpEchoServer {//创建一个DatagramSocket对象 这个就相当于一个网卡文件private DatagramSocket socket = null;public UdpEchoServer(int port) throws SocketException {//这样写就是手动指定端口socket = new DatagramSocket(port);//socket = new DatagramSocket();  这样写就是系统自动分配端口}public void start() throws IOException {System.out.println("服务器启动!");while (true) {//1. 读取请求并解析//这里首先要创建出数据报类型的对象//此处的requestPacket对象就是作为输出型参数进行传递DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//在receive之后,requestPacket中已经存储好了二进制数据//但是要想显示出来,就需要把这个二进制转为字符串//此处意思就是从 0 到数据的最大长度String request = new String(requestPacket.getData(),0,requestPacket.getLength());//2.根据请求计算相应//由于是回显服务器,请求是啥样,相应就是啥样String response = process(request);//3.把响应写回到客户端中//此时搞一个响应对象,DatagramPacket,在这个里面构造刚才的数据,再返回//注意response.getBytes().length 和 response.length 是不一样的,// 一个是获取字节的长度,另一个是获取字符的长度。如果response全是英文字符串,那就没事。但是如有中文的话就可能会出现问题DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);//打印日志文件System.out.printf("[%s:%d] req=%s, resp=%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}private String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer server = new UdpEchoServer(9090);server.start();}
}

代码解读:

1. 服务器要手动指定端口, socket = new DatagramSocket(port); 这样的目的就是让多个客户端能够精准访问。

2. process 方法就是一个简单的 传进去什么,返回什么东西。这个就是回显的体现。

3.DatagramSocket 有不同的版本 , 我们要根据需要 使用不同的参数.

        比如在服务器进行接收的时候,就需要先构造好一个空的DatagramSocket对象(相当于空盘子),然后放到recevie里面等待客户端发来东西。然后把客户端的东西放到这个对象中(放到盘子里)。

        比如在服务器进行回应的时候,此时的DatagramSocket里面就应该是response ,也就是根据这个response 字符串进行构造DatagramSocket对象。

4.requestPacket.getSocketAddress() 意思就是服务器回应的时候,需要知道是谁发来的。

2.客户端部分 

package net;import Inner.Inter;import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket = null; //先制定网关文件为空private String serverIp = "";private  int serverPort = 0; //端口号public UdpEchoClient(String ip,int port) throws SocketException {//客户端这边就是手动指定端口socket = new DatagramSocket();serverIp = ip;serverPort = port;}public void start() throws IOException {System.out.println("客户端启动!");Scanner scanner = new Scanner(System.in);while (true) {//1.从控制台读取数据,作为请求System.out.print("-> ");String request = scanner.next();//2.将请求内容构造成DatagramPacket数据报对象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 response = new String(responsePacket.getData(),0, responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("172.0.0.1",9090);client.start();}
}

代码解读:

1. 客户端需要使用系统自动分配的端口。这是为什么呢?我们来想一下,加入我在我们大学开了一个窗口,那么我就是一个服务器,也就是给大家做饭的。各位同学们就是客户端。那么我的窗口位置就需要确定,以让同学们更好的找到我(也就是服务器的端口要手动指定)。那么各位同学在等待我做好饭的时候(等待服务器回应),所等待的位置是不是每次都相同?答案很明显:不是。 同学们等待我做饭的位置,是不定的!!!也就是可以理解为客户端的端口是随机的,是系统自动分配的

2. 知道需要分配端口号之后,客户端这边需要发送一个请求给服务器。那么这个请求需要构造成DatagramSocket 对象类型,才能够进行传输。

3.InetAddress.getByName(serverIp) 这个就是将服务IP 转化为数据报的形式,因为我们自己写的IP是字符串。

4. 客户端通过sent发送请求,然后receive等待相应。注意等待相应之前,应该先有一个空的DatagramSocket对象(空盘子)来接收这个相应!

 3. 具体的流程到底是个啥?

1). 首先服务器先启动。服务器启动之后,就会进入循环,执行到 receive 这里进行阻塞(因为客户端还没有发送请求过来);

2). 客户端也开始启动, 先进入while 循环 执行 scanner.next 并且也在这里阻塞. 直到用户输入一个内容

3). 客户端发送数据之后(服务器和客户端会同步执行)

     服务器: 就会从receive 中返回, 进一步的解析请求为字符串 , 指定 process方法, 执行sent 操作,执行打印操作.

     客户端:  继续往下执行,指定到客户端的 receive阻塞, 等待服务器的响应

4). 客户端收到从服务器返回的数据之后 , 就会从 receive 中停止阻塞并返回 . 然后执行打印操作

5). 服务器这边完成一次循环之后 , 又执行到了 receive这里

    客户端这边完成一次循环之后, 执行到了 scanner.next 这里

        双双进入阻塞, 如此再循环往复~~~~~

4.执行结果


总结: 写UDP版本的环回服务器 + 客户端的过程可以加深我们对于网络编程的细节概念。到这里我们就突破了次元壁,大家可以尝试在局域网内互相发送消息。只需要将服务器文件发送给另一台电脑并且执行,客户端这边改一下 IP 就可以了。大家可以尝试一下!

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

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

相关文章

Qt Designer中各个模块的详细介绍,小白一看就会!!第3部分——Item Views (Model-Based) 模块介绍

Item Views (Model-Based) 模块的详细介绍 在Qt Designer中,Item Views (Model-Based) 模块是一组基于模型/视图(Model/View)架构的控件,用于展示和操作数据。这些控件与数据模型紧密结合,使得数据展示变得更加灵活和…

SAP问题 OPEN SQL 取不到值

关键:数据库中有数据,但是open sql取不到数据 背景: 标准程序在测试环境正常执行,在生产环境报错。 解决过程: 第一步:分析执行结果不一致可能的原因: 1.测试数据问题,可能性小&…

lv13 内核模板编译方法 7

1 内核模块基础代码解析 Linux内核的插件机制——内核模块 类似于浏览器、eclipse这些软件的插件开发,Linux提供了一种可以向正在运行的内核中插入新的代码段、在代码段不需要继续运行时也可以从内核中移除的机制,这个可以被插入、移除的代码段被称为内…

Python将普通图像转化为栅格影像

引言 本人研究的方向是遥感,研究了2年也搞没清楚普通图像和遥感影像的区别,只知道到了多了地理坐标信息,但是经纬度信息映射到每个图像像素点的底层逻辑我还不太理解。因为现在需要使用python将图像转化为栅格影像,所以在此仔细研…

园林机械部件自动化三维测量检测形位公差-CASAIM自动化三维检测工作站

随着园林机械的广泛应用,对其机械部件的精确测量需求也日益增加。传统的测量方法不仅效率低下,而且精度难以保证,因此,自动化三维测量技术成为了解决这一问题的有效途径。本文将重点介绍CASAIM自动化三维检测工作站在园林机械部件…

51系列--拨码开关编码控制的数码管显示设计

本文介绍基于51单片机的拨码开关编码控制的数码管显示设计(完整Proteus仿真源文件及C代码见文末链接) 一、系统及功能介绍 本设计主控芯片选用51单片机,主要实现拨码开关开关不同组合的数值在4位数码管上显示出来,拨码开关一共是…

关于Sql数据库中去掉字段的所有空格

这篇文章主要介绍了Sql数据库中去掉字段的所有空格小结篇,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 − Sql数据库中去掉字段的所有空格 字符前的空格,用ltrim(string) 字符…

机器学习的一般步骤

机器学习专注于让机器从大量的数据中模拟人类思考和归纳总结的过程,获得计算模型并自动判断和推测相应的输出结果。机器学习的一般步骤可以概括为以下几个阶段: 数据收集和准备: 收集与问题相关的数据,并确保数据的质量和完整性。…

微服务全链路灰度方案介绍

目录 一、单体架构下的服务发布 1.1 蓝绿发布 二、微服务架构下的服务发布 三、微服务场景下服务发布的问题 四、全链路灰度解决方案 4.1 物理环境隔离 4.2 逻辑环境隔离 4.3 全链路灰度方案实现技术 4.3.1 标签路由 4.3.2 节点打标 4.3.3 流量染色 4.3.4 分布式链路…

java美容管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web美容管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…

子网掩码与IP段计算

一.什么叫子网掩码: 子网掩码(subnet mask)又叫网络掩码、地址掩码、子网络遮罩,它用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。子网掩码不能单独存在,它必须结合IP地址一起使用。 子网掩…

【源码】-MyBatis-如何系统地看源码

写在前面 前段时间做过一个项目,期间用到了动态数据源dynamic-datasource,经历了dbcp2的数据库连接池没有生效到排查定位、MyBatis多种数据库产品兼容、手写MyBatis拦截器等事情。 花费了好久,一直在打磨这篇文章(不知道花费这么长…

光电耦合器:什么是隔离放大器

隔离放大器是现代电子系统中的关键组件,在维持信号完整性和确保敏感设备的安全方面发挥着关键作用。隔离放大器采用的关键技术之一是光耦合器,这是一种设计用于传输信号同时电隔离输入和输出电路的器件。在本文中,我们深入研究隔离放大器领域…

基于Java网上点餐系统设计与实现

博主介绍: ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精彩专栏 推荐订阅 👇🏻 不然下次找不到 Java项目精品实…

提供电商API-100+接口,等你来试用(免费测试)

什么是 API 调用? 应用程序编程接口 (API)是一个程序与另一个程序交互的一种方式。API 调用是它们交互的媒介。API 调用(或 API 请求)是发送到服务器的消息,要求 API 提供服务或信息。 如果 Jan 招待很多客人共进晚餐&#xff0c…

Linux磁盘阵列

一.RAID磁盘阵列介绍 RAID(Redundatnt Array of lndependent Disks),全称为:独立冗余磁盘阵列 解释: RAID是一种把多块独立的硬盘(物理硬盘)按不同的方式组合起来形成一个硬盘组(逻…

netstat命令使用

在线安装 yum install -y net-tools 离线安装 下载本文关联的资源 解压得到离线安装包 拷贝到服务器 执行离线安装命令,需要在rpm文件所在路径执行 # 离线安装 rpm -Uvh --force --nodeps *.rpm 使用 netstat -nltp

【华为机试】2023年真题B卷(python)-解密犯罪时间

一、题目 题目描述: 警察在侦破一个案件时,得到了线人给出的可能犯罪时间,形如 “HH:MM” 表示的时刻。 根据警察和线人的约定,为了隐蔽,该时间是修改过的,解密规则为: 利用当前出现过的数字&am…

Python武器库开发-武器库篇之上传本地仓库到Git(三十八)

武器库篇之上传本地仓库到Git(三十八) 当我们在Git中创建远程仓库和进行了SSH key免密登陆之后,我们点击 Your respositories 可以查看我们所创建的远程仓库,如图所示: 如果我们需要将本地的仓库上传到Git,首先我们需要建立一个本…