Java基础14-网络编程

十四、网络编程

java.net.*包下提供了网络编程的解决方案!

基本的通信架构

基本的通信架构有2种形式: CS架构( Client客户端/Server服务端)、BS架构(Browser浏 览器/Server服务端)。无论是CS架构,还是BS架构的软件都必须依赖网络编程!。

1、网络通信的三要素

网络通信的三要素:IP地址、端口、协议。

1.1 InetAddress

代表IP地址,是一个操作IP地址的类。

InetAddress的常用方法说明
public static InetAddress getLocalHost()获取本机IP,会以一个InetAddress对象返回
public static InetAddress getByName( String host )根据ip地址或者域名,返回一个InetAddress对象
public String getHostName()获取指定IP对象对应的主机名
public String getHostAddress()获取指定IP地址对象中的IP地址信息
public boolean isReachable(int timeout )在指定毫秒内,判断主机与该IP对应的主机是否能连通
public class InetAddressTest   {public static void main(String[] args) throws Exception {//获取本机IP地址对象InetAddress  localhost=InetAddress.getLocalHost();//获取指定IP对象的IP地址String   lip=  localhost.getHostAddress();//获取指定IP对象的主机名String   name=localhost.getHostName();System.out.println(lip);System.out.println(name);//获取指定IP地址或域名的Ip对象InetAddress   baidu= InetAddress.getByName("www.baidu.com");//获取指定IP对象的IP地址System.out.println(baidu.getHostAddress());//获取指定IP对象的主机名System.out.println(baidu.getHostName());//判断指定IP对象在1秒内是否与本机是否可以连通boolean  isComm=baidu.isReachable(1000);System.out.println(isComm);}
}
1.2、端口

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

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

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

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

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

1.3、协议

开放式网络互联标准::OSI网络参考模型,是全球网络互联标准。

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

UDP(User Datagram Protocol): 用户数据报协议; TCP(Transmission Control Protocol) :传输控制协议。

在这里插入图片描述

1.3.1 UDP协议

特点::通信效率搞、无连接、不可靠通信。

不事先建立连接,数据按照包发,一包数据包含:自己的IP、程序端口,目的地IP、程序端口和数据(限制在64KB内),超过就分包发送。

发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,故是不可靠的。

场景:视频语音通话、网络直播。

1.3.2、TCP协议

特点:通信效率相对不高、面向连接、可靠通信。

TCP的最终目的:要保证在不可靠的信道上实现可靠的传输。

TCP主要有三个步 骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接。

场景:文件下载、网页、支付。

2、UDP通信

特点:无连接、不可靠通信。

不事先建立连接,发送端每次把要发送的数据(限制在64KB内)、接收端IP、 等信息封装成一个数据包, 发出去就不管了。

Java提供了一个java.net.DatagramSocket类来实现UDP通信。

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

构造器说明
public DatagramSocket()创建客户端的Socket对象,系统会随机分配一个端口号
public DataGramSocket( int port )创建服务器的Socket对象,并指定端口号
DatagramSocket对象提供的方法说明
public void send(DatagramPacket dp)发送数据包
public void receive( DatagramPacket p )使用数据包接收数据

DatagramPacket:创建数据包

构造器说明
public DatagramPacket(byte[] buf , int length , InetAddress address , int port )创建发出去的数据包对象
public DatagramPacket(byte[] buf , int length )创建用来接收数据的数据包
方法说明
public int getLength()获取数据包,实际接收到的字节个数

1、客户端向服务端发送UDP信息——一发一收

//客户端
public class Client {public static void main(String[] args) throws Exception {//1、获取客户端对象DatagramSocket  socket=new DatagramSocket();//2、准备数据,将字符串转为字符数组byte[]  hi= "你好Java,Hello Java".getBytes();//3、创建发送数据的数据包,参数:(发送数据的字节数组,数据字节大小,接收方的IP地址对象(这里是本机),接收方开放的端口)DatagramPacket packet=new DatagramPacket(hi,hi.length, InetAddress.getLocalHost(),6060);//4、调用客户端对象的发送方法,将数据包对象作为参数,发送数据。socket.send(packet);//5、关闭发送接口socket.close();System.out.println("客户端发送完毕!");}
}
//服务端
public class Service {public static void main(String[] args) throws Exception {//1、创建服务端的对象(端口号要和客户端一样)DatagramSocket socket=new DatagramSocket(6060);System.out.println("-----服务端启动----");//限制接收数据的字节数(最大64kb)byte[]  buffer=new byte[1024*64];//2、创建接收数据包的对象,参数(接收字节的数组,限制接收字节的大小)DatagramPacket packet=new DatagramPacket(buffer,buffer.length);//3、通过服务端对象的方法接收数据socket.receive(packet);//4、获取到接收的数据//获取接收数据的大小int   len=packet.getLength();//由于用来装数据的数组是最大来算的(64kb),很可能装不满,所有接收多少,倒多String str=new String(buffer,0,len);System.out.println(str);//关闭服务端socket.close();}
}

2、客户端向服务端发送UDP信息——用户控制多次发送

使用死循环来实现

//客户端
public class Client {public static void main(String[] args) throws Exception {Scanner  scanner=new Scanner(System.in);//1、获取客户端对象DatagramSocket  socket=new DatagramSocket();while (true) {System.out.print("请输入发送内容:");//2、准备数据,将字符串转为字符数组String say= scanner.next();if (!say.equals("0")) {//3、创建发送数据的数据包,参数:(发送数据的字节数组,数据字节大小,接收方的IP地址对象(这里是本机),接收方开放的端口)DatagramPacket packet=new DatagramPacket(say.getBytes(),say.getBytes().length, InetAddress.getLocalHost(),6060);//4、调用客户端对象的发送方法,将数据包对象作为参数,发送数据。socket.send(packet);System.out.println("已发送!");}else {break;}}//5、关闭发送接口socket.close();}
}
//服务端
public class Service {public static void main(String[] args) throws Exception {//1、创建服务端的对象(端口号要和客户端一样)DatagramSocket socket=new DatagramSocket(6060);System.out.println("-----服务端启动----");//限制接收数据的字节数(最大64kb)byte[]  buffer=new byte[1024*64];while (true) {//2、创建接收数据包的对象,参数(接收字节的数组,限制接收字节的大小)DatagramPacket packet=new DatagramPacket(buffer,buffer.length);//3、通过服务端对象的方法接收数据socket.receive(packet);//4、获取到接收的数据//获取接收数据的大小int   len=packet.getLength();//由于用来装数据的数组是最大来算的(64kb),很可能装不满,所有接收多少,倒多String str=new String(buffer,0,len);System.out.println("已接收内容:"+str);}//关闭服务端// socket.close();}
}

3、TCP通信

特点:面向连接、可靠通信。

通信双方事先会采用“三次握手”方式建立可靠连接,实现端到端的通信;底层能保证数据成功传给服务端。

1、TCP客户端开发

Java提供了一个java.net.Socket类 来实现TCP通信。

Socket类构造器说明
public Socket(String host,int port)根据指定的服务器IP、端口号请求与服务器建立连接,连接通过,就获得了客户端socket
方法说明
public OutputStream getOutputStream( )获得字节输出流对象
public InputStream getInputStream()获得字节输入流对象
public class TcpClient {public static void main(String[] args) throws Exception {//1、创建一个Socket对象,并同时请求服务器进行连接(传入要发送给服务端的IP和对应的端口号)Socket  socket=new Socket(InetAddress.getLocalHost().getHostAddress(),6060);//2、通过调用字节输出流OutputStream os= socket.getOutputStream();//3、将原始字节输出流转为数据字节输出流(性能更好)DataOutputStream  dos=new DataOutputStream(os);//4、调用写出方法dos.writeUTF("通过TCP协议发送信息");//5、关闭字节流dos.close();//6、释放连接资源socket.close();}
}

2、TCP服务端开发

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

ServerSocket类构造器说明
public ServerSocket( int port )为服务端程序注册端口
方法说明
public Socket accept()阻塞等待客户端的连接请求,一旦与某个客户端连接成功,则返回服务端这边的Socket对象
//服务端
public class TcpService {public static void main(String[] args) throws Exception {//1、创建一个服务端连接对象serverSocket,并设置服务端端口ServerSocket  serverSocket=new ServerSocket(6060);//2、调用accept方法,监测是否又客户端发起连接,连接成功,返回Socket对象Socket  socket=serverSocket.accept();//3、通过Socket对象,调用字节输入流InputStream  is=socket.getInputStream();//4、为提高性能,将原始字节流转换为数据字节流DataInputStream dis=new DataInputStream(is);//5、调用读方法,读出发送过来的数据String  str=  dis.readUTF();System.out.println(str);//6、关闭字节流dis.close();//7、释放资源serverSocket.close();}
}
3.1 TCP客户端和服务端开发-多收多发

这个案例只能接收一个程序的信息,没法实现接收多个客户端发送的信息:因为服务端现在只有一个主线程,只能处理一个客户端的消息。

//服务端
public class TcpService {public static void main(String[] args) throws Exception {System.out.println("------服务端已启动--------");//1、创建一个服务端连接对象serverSocket,并设置服务端端口ServerSocket  serverSocket=new ServerSocket(6060);//2、调用accept方法,监测是否又客户端发起连接,连接成功,返回Socket对象Socket  socket=serverSocket.accept();//3、通过Socket对象,调用字节输入流InputStream  is=socket.getInputStream();//4、为提高性能,将原始字节流转换为数据字节流DataInputStream dis = new DataInputStream(is);while (true) {//5、调用读方法,读出发送过来的数据try {String  str=  dis.readUTF();System.out.println("已接收:"+str);} catch (Exception e) {//如果客户端退出,那么服务端,会出异常,这时就可以捕获异常,进行处理(获取离线的IP)System.out.println(socket.getRemoteSocketAddress()+":已离线");//释放资源dis.close();socket.close();break;}}}
}
//客户端
public class TcpClient {public static void main(String[] args) throws Exception {//1、创建一个Socket对象,并同时请求服务器进行连接(传入要发送给服务端的IP和对应的端口号)Socket  socket=new Socket(InetAddress.getLocalHost().getHostAddress(),6060);//2、通过调用字节输出流OutputStream os= socket.getOutputStream();//3、将原始字节输出流转为数据字节输出流(性能更好)DataOutputStream  dos=new DataOutputStream(os);Scanner scanner=new Scanner(System.in);while (true) {System.out.print("请说:");String str=scanner.nextLine();if(str.equals("0")){//5、关闭字节流dos.close();//6、释放连接资源socket.close();break;}//4、调用写出方法dos.writeUTF(str);}}
}
3.2 TCP客户端和服务端开发-接收多客户端信息

通主线程接接收倒Socket对象,主线程将其交给一个子线程来处理,每多一个socket就交给一个子线程。

在这里插入图片描述

//客户端
public class TcpClient {public static void main(String[] args) throws Exception {//1、创建一个Socket对象,并同时请求服务器进行连接(传入要发送给服务端的IP和对应的端口号)Socket  socket=new Socket(InetAddress.getLocalHost().getHostAddress(),6060);//2、通过调用字节输出流OutputStream os= socket.getOutputStream();//3、将原始字节输出流转为数据字节输出流(性能更好)DataOutputStream  dos=new DataOutputStream(os);Scanner scanner=new Scanner(System.in);while (true) {System.out.print("请说:");String str=scanner.nextLine();if(str.equals("0")){//5、关闭字节流dos.close();//6、释放连接资源socket.close();break;}//4、调用写出方法dos.writeUTF(str);}}
}
//服务端
public class TcpService {public static void main(String[] args) throws Exception {System.out.println("------服务端已启动--------");//1、创建一个服务端连接对象serverSocket,并设置服务端端口ServerSocket  serverSocket=new ServerSocket(6060);Socket  socket= null;while (true) {//2、调用accept方法,监测是否又客户端发起连接,连接成功,返回Socket对象socket = serverSocket.accept();//将Socket对象交给子线程进行处理new SocketServerThread(socket).start();}}
}
//线程类
public class SocketServerThread extends Thread {
private  Socket  socket;
public SocketServerThread(Socket socket){this.socket=socket;
}@Overridepublic void run() {try {//调用Accent方法获取字节输入流InputStream is=socket.getInputStream();//将原始流转换为数据流DataInputStream dis=new DataInputStream(is);//可以获取到是哪个客户端发送的IPSystem.out.println(socket.getRemoteSocketAddress()+":已上线!");while (true) {try {//读取客户端发送的信息(只要不下线就一直处理该客户端的信息)String str= dis.readUTF();System.out.println(str);} catch (Exception e) {//下线System.out.println(socket.getRemoteSocketAddress()+":一下线!");//释放资源dis.close();socket.close();}}} catch (Exception e) {e.printStackTrace();}super.run();}
}
3.3 案例

实现群聊,一个客户端发送的信息,会被其它所有在线的客户端接收到。

每个客户端的socket还是交给服务端一个子线程进行处理,如果上线就将socket对象用集合保存起来,用来转发信息,如果下线就将其删除掉。

在这里插入图片描述

3.4 B/S架构

在这里插入图片描述

HTTP协议规定:响应给浏览器的数据格式必须满足如下格式:

在这里插入图片描述

通过浏览器进行访问直接访问环路地址加端口(127.0.0.1:8080)

//服务端
public class Server {public static void main(String[] args) throws Exception {System.out.println("------服务端启动-------");//1、创建一个serverSocket对象,开放服务器端口ServerSocket serverSocket=new ServerSocket(8080);//2、创建一个线程池,防止高并发ThreadPoolExecutor pool=new ThreadPoolExecutor(4*2,4*2,5, TimeUnit.MINUTES,new ArrayBlockingQueue<>(8), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());while (true) {//3、通过serverSocket对象获取socket对象Socket socket=serverSocket.accept();//4、创建线程对象,并将线程对象交给线程池pool.execute(new ServerRunnable(socket));}}
}
//线程类
public class ServerRunnable implements Runnable {private Socket socket;public ServerRunnable(Socket socket) {this.socket=socket;}@Overridepublic void run() {try {//1、通过传过来的socket对象获取字节输出流OutputStream os=socket.getOutputStream();//2、将原始输出流转换为输出字节流PrintStream ps=new PrintStream(os);//3、调用输出流方法,按照浏览器输出规则输出对应内容ps.println("HTTP/1.1 200 OK");ps.println("Content-Type:text/html");ps.println();   //必须换行ps.println("<div style='font-size:200px;color:green; text-align:center;'>Hello  world<div/>"); //输出html格式或者直接字符串//释放资源ps.close();socket.close();} catch (Exception e) {e.printStackTrace();}}
}

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

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

相关文章

堡垒机安装、链接服务器、数据库

堡垒机 JumpServer - 开源堡垒机 - 官网 下载安装包 jumpserver jumpserver.org (.org开源) 1、将安装包上传至虚拟机 &#xff08;1&#xff09;rz上传 &#xff08;2&#xff09;lftp登录 put下载 2、解压 [roothostname ~]# tar -xf jumpserver-ce-v4.2.0-x86_64.t…

认识Java的异常

异常机制 异常机制指的是程序出现错误时&#xff0c;程序的处理方式。 程序的错误分为三种&#xff1a; 编译错误&#xff1a;由于没有遵循对于语言的语法规则&#xff0c;编辑器可以自动发现并提示的错误位置和原因。逻辑错误&#xff1a;程序没有按照预期的顺序执行。运行…

Reality Capture 软件安装 附下载链接

Reality Capture 软件安装 文章目录 Reality Capture 软件安装一、Reality Capture v1.4汉化版安装包下载并解压二、Epic Games Launcher安装三、设置路径并安装![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f077210990674d9fa9c10b52338b52fe.png)四、启动Epic Ga…

第十四届中国国际健康产品展览会在沪举办,无限未来品牌大放异彩

2024 年&#xff0c;第十四届中国国际健康产品展览会、2024 亚洲天然及营养保健品展在上海成功举办。 此次展会聚焦天然及营养保健品领域&#xff0c;来自香港的 INFINITE FUTURE 无限未来品牌脱颖而出。无限未来将先进的营养科学与尖端数字技术融合&#xff0c;开发专业级营养…

Stylized Far East 古代国风建筑城镇宫殿场景模型

古代国风建筑城镇宫殿场景模型。内容: -演示场景(截图) - 种类繁多的建筑,如宫殿、商店、神社、房屋、餐馆、宝塔、寺庙等 -带有塔楼、门楼的模块化城堡墙 -树木、岩石、悬崖和其他自然资产 -传统装饰,如纸灯笼、绘画、瓷器等 - 城镇道具,如手推车、栅栏、板条箱、市场、…

【JavaEE】——TCP应答报文机制,超时重传机制

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;TCP协议&#xff08;面试重点重点&#xff09; 1&#xff1a;报头长度 2&#xff1a;…

今年双十一可以买啥?2024双十一不用做功课闭眼入的品牌好物分享!

今年的双十一购物狂欢节即将来临&#xff0c;许多消费者已经开始规划他们的购物清单&#xff0c;期待在这个一年一度的促销盛会上抢购到心仪的商品。2024年的双十一&#xff0c;你无需再做繁琐的功课&#xff0c;因为这里将为你分享一些闭眼入的品牌好物&#xff0c;让你轻松享…

unity Gpu优化

不一样的视角&#xff0c;深度解读unity性能优化。unity性能优化&#xff0c;unity内存优化&#xff0c;cpu优化&#xff0c;gpu优化&#xff0c;资源优化&#xff0c;资源包、资源去重优化&#xff0c;ugui优化。 gpu优化静态批处理静态批处理原理规则静态合批的原理静态合批的…

【Sceneform-EQR】(手势优化)通过手势事件实现在AR/VR等三维场景中的控制模型旋转、平移与缩放

在上一篇文档中&#xff0c;我们实现了通过手势控制模型节点的旋转、缩放和平移。现在本文将介绍如何优化上一篇做的手势控制器&#xff0c;从而实现更好的跟手效果。 相关链接&#xff1a;【Sceneform-EQR】&#xff08;手势控制器实现&#xff09;通过手势事件实现在AR/VR等…

网络安全中的RCE命令执行漏洞----入门小白必看

RCE命令执行&代码执行漏洞 RCE命令执行漏洞 RCE漏洞简介 RCE(remote code/command execute) 远程代码/命令执行漏洞 RCE漏洞是两个漏洞&#xff1a; 代码执行漏洞 # 针对后端语言!命令执行漏洞 # 针对系统! 如何产生 在 Web应用中有时候程序员为了考虑灵活性、简洁性…

【SEO】什么是SEO?

什么是SEO&#xff08;搜索引擎优化&#xff09;&#xff1f;为什么SEO对于⼀个⽹站⾄关重要&#xff1f; SEO 全称是搜索引擎优化&#xff08;Search Engine Optimization&#xff09; 因为我们目前开发的网址&#xff0c;需要人看到&#xff0c;除了通过宣传营销的方式展现…

前端布局与响应式设计综合指南(二)

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Css篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Css篇专栏内容:前端布局与响应式设计综合指南(二) 目录 23、行内元素和块级元素&#xff1f;img算什么&…

影刀RPA实战:操作Mysql数据库

1.摘要 影刀RPA&#xff08;Robotic Process Automation&#xff09;是一种软件自动化工具&#xff0c;它可以模拟人类用户执行各种重复性任务&#xff0c;其中包括对数据库的操作。 我们可以使用软件自动化指令&#xff0c;通过获取数据库窗口对象来操作数据库&#xff0c;也…

《探秘数据合规官CCRC-DCO人员能力验证》

在当今竞争激烈的商业世界中&#xff0c;“数据合规官CCRC-DCO人员能力验证”这个词逐渐走入人们的视野。但究竟什么是数据合规官CCRC-DCO人员能力验证呢&#xff1f; 首先&#xff0c;咱们来明确一下概念。数据合规官CCRC-DCO人员能力验证&#xff0c;简单来说&#xff0c;就…

数仓范式建模和维度建模有什么不同?

在数据库设计的复杂世界中&#xff0c;还有一类建模方法&#xff0c;为范式建模&#xff0c;是一种旨在优化数据库结构、提高数据一致性和完整性的设计方法。本文将深入探讨范式建模的概念、原理、步骤以及与维度建模的区别。 一、什么是范式建模&#xff1f; 范式建模是一种…

Chromium 中window.DOMParser接口说明c++

一、DOMParser DOMParser 可以将存储在字符串中的 XML 或 HTML 源代码解析为一个 DOM Document。 备注&#xff1a; XMLHttpRequest 支持从 URL 可寻址资源解析 XML 和 HTML&#xff0c;在其response 属性中返回Document。 你可以使用XMLSerializer 接口执行相反的操作 - 将…

接口测试自动化后起之秀-YApi接口管理平台

前言 众多接口管理工具如雨后春笋&#xff0c;让人欣慰的是&#xff0c;有许多优秀作品来自国内&#xff0c;包含Yapi和rap&#xff0c;看着中文的官网&#xff0c;华丽的汉语&#xff0c;不禁让人大快朵颐&#xff0c;暗自称爽。当然这也就带来另一个弊端&#xff0c;使用基数…

nodejs的卸载和nvm安装

由于项目需求&#xff0c;需要多版本控制的nodejs&#xff0c;所以要把原来的nodejs卸载干净&#xff0c;然后再装nvm 常见问题 1.在安装nvm的时候没有卸载node&#xff0c;导致使用nvm安装完之后&#xff0c;node和npm都不可用。 2.在第一次使用nvm安装node后&#xff0c;要…

从零开始使用最新版Paddle【PaddleOCR系列】——第二部分:自建数据集 + 模型微调训练

目录 一、自建数据集 1.官方数据集格式参考 2.自建数据集txt文件编写代码 3.数据集检验 二、模型训练 1.模型配置yaml文件 2.命令行指令训练 在上一篇文章中&#xff0c;构建好了paddleOCR 运行必需的环境&#xff0c;并通过在线下载的方式&#xff0c;使用官方训练好的模型进…

深入理解 JDK 的 Optional 类

深入理解 JDK 的 Optional 类 深入理解 JDK 的 Optional 类1. 什么是 Optional&#xff1f;1.1 主要构造方法示例 2. Optional 的常用方法2.1 判断值是否存在示例2.2 获取值示例2.3 进行操作示例 3. 使用场景3.1 避免 null 值示例3.2 提高代码可读性3.3 与流结合示例 4. 注意事…