JavaSE——网络编程

一、InetAddress类

        InetAddress是Java中用于封装IP地址的类。

获取本机的InetAddress对象:

InetAddress localHost = InetAddress.getLocalHost();

根据指定的主机名获取InetAddress对象(比如说域名)

InetAddress host = InetAddress.getByName("www.baidu.com");

通过InetAddress对象获取对应的地址 

String hostAddress = host.getHostAddress();

通过InetAddress对象获取对应的主机名或者是域名

String hostAName = host.getHostName();

二、Socket 

        套接字(Socket)在开发网络应用程序中被广泛采用,以至于称为事实上的标准,它允许数据在两个Socket间通过IO传输。

流式套接字

        基于TCP协议,提供面向连接、可靠的数据传输服务。它保证数据的顺序性、完整性和可靠性,适用于对数据传输质量要求较高的场景,如文件传输、远程登录等。在Java中,使用Socket类来表示流式套接字。

数据报套接字

        基于UDP协议,提供无连接、不可靠的数据传输服务。它不保证数据的顺序性、完整性和可靠性,但传输速度快,适用于对实时性要求较高、对数据丢失不敏感的场景,如视频直播、在线游戏等。在Java中,使用DatagramScoket类和DatagramPacket类来实现数据报套接字通信。

        一般来讲,主动发起通信的应用程序属于客户端,等待通信请求的为服务端。

三、TCP网络通信编程

3.1TCP套接字通信原理

3.1.1服务端

  1. 创建ServerSocket:服务器端首先创建一个ServerSocket对象,并绑定到一个特定的端口,等待客户端的连接请求。

    ServerSocket ss = new ServerSocket(8888);

    表示服务器端在本地的 8888 端口上创建一个ServerSocket,准备接收客户端的连接。

  2. 监听连接请求:服务器端通过ServerSocket的accept方法监听客户端的连接请求。当没有客户端发起连接请求时,accept方法会阻塞等待,直到接收到一个连接请求,然后返回一个新的Socket对象,该Socket对象代表了服务器端与客户端之间的连接。

    Socket socket = ss.accept();

    表示服务器端接受了一个客户端的连接请求,并创建了一个新的Socket对象来与该客户端进行通信。

  3. 数据传输:可以使用socket.getInputStream()获取输入流,用于接收客户端发送的数据;使用socket.getOutStream()获取输出流,用于向客户端发送数据。

  4. 关闭连接:数据传输完成后,服务器端需要关闭与客户端的连接,释放资源。

3.1.2客户端

  1. 创建Socket:客户端创建一个Socket对象,并指定服务器端的IP地址和端口号,发起连接请求。
    Socket socket = new Socket(InetAddress.getLocalHost(),8888);
  2. 数据传输:连接建立后,客户端通过Socket对象的输入流和输出流与服务器端进行数据传输。与服务器端类似,客户端也可以使用socket.getInputStream和socket.OutputStream获取输入流和输出流,进行数据的读写操作。

  3. 关闭连接:数据传输完成后,客户端需要关闭连接,释放资源。

3.2TCP字节流编程实例

        要求客户端向服务端发送hello serve,服务端受到后返回hello client。

服务端:

//1. 在本机 的 9999 端口监听, 等待连接
// 细节: 要求在本机没有其它服务在监听 9999
// 细节:这个 ServerSocket 可以通过 accept() 返回多个 Socket[多个客户端连接服务器的并发]
ServerSocket ss = new ServerSocket(8888);
System.out.println("客户端监听中");//如果没有客户端来连接,程序会阻塞等待连接
//如果有客户端连接则会返回socket对象,程序继续
Socket socket = ss.accept();
System.out.println("客户端IP" + socket.getInetAddress().getHostAddress());//2.通过socket.getInputstream()读取客户端写入到数据通道的数据
InputStream inputstream = socket.getInputStream();//IO读取
int readln = 0;
byte[] bytes = new byte[1024];
while((readln = inputstream.read(bytes)) != -1){System.out.println(new String(bytes,0,readln));
}
socket.shutdownInput();//3.通过socket.getOutputStream()给客户端发送数据
OutputStream outputstream = socket.getOutputStream();
outputstream.write("hello client".getBytes());//4.关闭流和socket
inputstream.close();
outputstream.close();
socket.close();
System.out.println("服务端退出");

客户端:

//1.连接服务端
Socket socket = new Socket(InetAddress.getLocalHost(),8888);
System.out.println("服务端IP" + socket.getInetAddress().getHostAddress());//2.连接上后,生成Socket,通过socket.getOutputstream()得到与socket对象相关连的输出流对象
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
//通过输出流,写入数据到数据通道
outputStream.write("hello serve".getBytes());
//设计结束标记
socket.shutdownOutput();//通过输入流,从通道中读取数据
byte[] buf = new byte[1024];
int readln = 0;
while ((readln = inputStream.read(buf)) != -1) {System.out.println(new String(buf, 0, readln));
}//3.关闭流和对象
outputStream.close();
inputStream.close();
socket.close();
System.out.println("客户端已关闭");

3.3TCP文件上传 

3.3.1一个工具类

public class StreamUtils {/*** 功能:将输入流转换成byte[]* @param is* @return* @throws Exception*/public static byte[] streamToByteArray(InputStream is) throws Exception{ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象byte[] b = new byte[1024];int len;while((len=is.read(b))!=-1){bos.write(b, 0, len);	}byte[] array = bos.toByteArray();bos.close();return array;}/*** 功能:将InputStream转换成String* @param is* @return* @throws Exception*/public static String streamToString(InputStream is) throws Exception{BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder builder= new StringBuilder();String line;while((line=reader.readLine())!=null){ //当读取到 null时,就表示结束builder.append(line+"\r\n");}return builder.toString();}}

        只需要知道这里的streamToByteArray方法将输入流的数据转换为byte[],streamToString方法将输入流转换为String。

3.3.2思路分析 

        先将磁盘上的图片转换成文件字节数组,通过Socket传输给服务端,服务端将得到的bytes文件写入到指定的路径中,向客户端回复 收到图片。

3.3.3服务端

//1.服务端在本机监听8888端口
ServerSocket ss = new ServerSocket(8888);
System.out.println("服务端在8888端口监听");//2.等待连接
Socket socket = ss.accept();//3.读取客户端发送的消息
//通过Socket得到输入流BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
byte[] bytes = StreamUtils.streamToByteArray(bis);//4.将得到的bytes数组写入到指定的路径中,就得到一个文件了
String str = "src\\my.jpg";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(str));
bos.write(bytes);
bos.close();//向客户端回复收到图片
//通过socket获取到输出流(字符)
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write("收到图片");
bw.flush();
socket.shutdownOutput();
//关闭其它资源
bw.close();
bis.close();
socket.close();
ss.close();

3.3.4客户端

//1.客户端连接服务端8888,得到Socket对象
Socket socket = new Socket(InetAddress.getLocalHost(),8888);//创建读取磁盘文件的输入流
String filePath = "D:\\My.jpg";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));//byte就是filePath对应的字节数组
byte[] bytes = StreamUtils.streamToByteArray(bis);//通过socket获取到输出流,将bytes数据发送给服务端
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(bytes);
bis.close();
socket.shutdownOutput();//接收从服务端回复的消息
InputStream inputStream = socket.getInputStream();
//使用StreamUtils的方法直接将inputStream读取到的内容转成字符串
String s  = StreamUtils.streamToString(inputStream);
System.out.println(s);//关闭相应的流
inputStream.close();
bos.close();
socket.close();

3.4TCP文件下载

3.4.1思路分析

         客户端将要下载的文件名传递给服务端,服务端返回对应文件,如果没有就返回默认。

3.4.2服务端

//1.监听 9999端口
ServerSocket serverSocket = new ServerSocket(9999);//2.等待端口连接
Socket socket = serverSocket.accept();//读取客户端发送要下载的文件名
InputStream inputStream = socket.getInputStream();
byte[] b = new byte[1024];
int len = 0;
String downLoadFileName = "";
while ((len = inputStream.read(b)) != -1) {downLoadFileName += new String(b,0,len);
}
System.out.println("用户希望下载的文件名=" + downLoadFileName);String resFileName = "";
if("高山流水".equals(downLoadFileName)){resFileName = "src\\高山流水.mp3";
}
else resFileName = "src\\无名.mp3";
//4.创建一个输入流,读取文件
BufferedInputStream bis =new BufferedInputStream(new FileInputStream(resFileName));//5.使用工具类StreamUtils,读取文件到一个字节数组
byte[] buffer = StreamUtils.streamToByteArray(bis);//6.得到Socket相关的输出流
BufferedOutputStream bos =new BufferedOutputStream(socket.getOutputStream());//写入到数据通道,返回给客户端
bos.write(buffer);
socket.shutdownOutput();//关闭相关资源
bos.close();
bis.close();
socket.close();
serverSocket.close();
System.out.println("服务端退出");

3.4.3客户端 

//1.接收用户输入,指定下载文件名
Scanner sc = new Scanner(System.in);
System.out.println("请指定下载文件名");
String downloadFileName = sc.nextLine();//2.客户端连接服务端,准备发送
Socket socket = new Socket(InetAddress.getLocalHost(),9999);//3.获取关联输出流
OutputStream os = socket.getOutputStream();
os.write(downloadFileName.getBytes());
//设置写入结束标志
socket.shutdownOutput();//4.读取服务端返回的文件
BufferedInputStream bis =new BufferedInputStream(socket.getInputStream());
byte[] buffer = StreamUtils.streamToByteArray(bis);//5.得到一个输出流,准备将bytes写入到磁盘文件
String filePath = "D:\\" + downloadFileName + ".mp3";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
bos.write(buffer);//关闭相关资源
bos.close();
bis.close();
os.close();
socket.close();
System.out.println("客户端已退出");

四、UDP网络通信编程

4.1 UDP通信原理

4.1.1发送端

  1. 创建DatagramSocket:发送端创建一个DatagramSocket对象,用于发送数据报。可以不指定端口号,让系统自动分配一个临时端口号;也可以指定一个端口号。
    DatagramSocket socket = new DatagramSocket();
    DatagramSocket socket = new DatagramSocket(8888);
  2. 创建DatagramPacket:发送端创建一个DatagramPacket对象,用于封装要发送的数据。需要指定数据内容、数据长度、接收端的 IP 地址和端口号。
    DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("server_ip"), 8888);
  3. 发送数据报:通过DatagramSocket的send(DatagramPacket p)方法发送数据报。
  4. 关闭DatagramSocket:数据发送完成后,发送端关闭DatagramSocket,释放资源。

4.1.2接收端

  1. 创建DatagramSocket:接收端创建一个DatagramSocket对象,并绑定到一个特定的端口上,用于接收数据报。
    DatagramSocket socket = new DatagramSocket(8888);
  2. 接收数据报:接收端通过DatagramSocket的reveive(Datagrampacket p)方法接收数据报。需要先创建一个Datagrampacket 对象作为接收容器,指定一个足够大的缓冲区来存储接收到的数据。
    byte[] buffer = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length); 
    socket.receive(packet);
  3. 处理数据:接收到数据报后,可以通过Datagrampacket对象获取数据内容、发送端的 IP 地址和端口号等信息。
    String receivedData = new String(packet.getData(), 0, packet.getLength()); 
    InetAddress senderAddress = packet.getAddress(); 
    int senderPort = packet.getPort();
  4. 关闭DatagramSocket:数据处理完成后,接收端关闭DatagramSocket,释放资源。

4.2UDP网络编程

4.2.1A端

//1.创建一个DatagramSocket对象,准备在9999端口接收数据
DatagramSocket socket = new DatagramSocket(9999);
//2.构建一个DatagramPacket对象,准备接收数据
//UDP协议一个数据包最大64k
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);//3.调用接收方法,将通过网络传输的DatagramPacket对象
//  填充到packet对象中
//如果没有数据包发送到本机的9999端口,就会阻塞等待socket.receive(packet);//4.可以把packet拆包取出数据,并显示
int len = packet.getLength();//实际接收到的数据字节长度
byte[] data  = packet.getData();//接收到数据
String s = new String(data,0,len);
System.out.println(s);//5.回复
byte[] buf2 = "好的".getBytes();
DatagramPacket packet2 = new DatagramPacket(buf2, buf2.length, InetAddress.getByName("192.168.31.130"),8888);
socket.send(packet2);
//关闭资源
socket.close();
System.out.println("A端退出");

4.2.2B端 

//1.创建DatagramSocket对象,准备在8888端口接收数据
DatagramSocket socket = new DatagramSocket(8888);//2.将需要发送的数据封装到DatagramPacket对象中
byte[] data = "hello 明天吃火锅".getBytes();//封装的DatagramPacket对象: data内容字节数组,data.length,主机IP,端口
DatagramPacket datagramPacket =new DatagramPacket(data, data.length, InetAddress.getByName("192.168.31.130"),9999);
socket.send(datagramPacket);//接收A端的回复
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
//拆包
int len = receivePacket.getLength();
byte[] receiveData2 = receivePacket.getData();
String s = new String(receiveData2,0,len);
System.out.println(s);
//关闭资源
socket.close();
System.out.println("B端退出");

 

 

 

 

 

 

 

 

 

 

 

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

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

相关文章

互联网全景消息(10)之Kafka深度剖析(中)

一、深入应用 1.1 SpringBoot集成Kafka 引入对应的依赖。 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupI…

G1原理—3.G1是如何提升垃圾回收效率

大纲 1.G1为了提升GC的效率设计了哪些核心机制 2.G1中的记忆集是什么 3.G1中的位图和卡表 4.记忆集和卡表有什么关系 5.RSet记忆集是怎么更新的 6.DCQ机制的底层原理是怎样的 7.DCQS机制及GC线程对DCQ的处理 提升G1垃圾回收器GC效率的黑科技 G1设计了一套TLAB机制 快速…

Elastic-Job相关

文档参考视频&#xff1a;09_SpringBoot案例演示_哔哩哔哩_bilibili 一、Elastic-Job介绍 Elastic-Job 是一个轻量级、分布式的任务调度框架&#xff0c;旨在解决分布式环境下的定时任务调度问题。 1.1. Elastic-Job 的核心组件 Elastic-Job 是由多个核心组件构成的&#x…

Spring Boot3 配合ProxySQL实现对 MySQL 主从同步的读写分离和负载均衡

将 ProxySQL 配合 Spring Boot 使用&#xff0c;主要的目的是在 Spring Boot 应用程序中实现对 MySQL 主从同步的读写分离和负载均衡。这样&#xff0c;你可以利用 ProxySQL 自动将写操作路由到主库&#xff0c;而将读操作路由到从库。 1. 准备工作 确保你的 MySQL 主从同步环…

TypeScript语言的并发编程

TypeScript语言的并发编程 引言 随着现代应用程序的复杂性不断增加&#xff0c;性能和用户体验的重要性显得尤为突出。在这种背景下&#xff0c;并发编程应运而生&#xff0c;成为提升应用程序效率的重要手段。在JavaScript及其超集TypeScript中&#xff0c;尽管语言本身是单…

【Linux】设备驱动中的ioctl详解

在Linux设备驱动开发中&#xff0c;ioctl&#xff08;输入输出控制&#xff09;是一个非常重要的接口&#xff0c;用于用户空间应用程序与内核空间设备驱动之间进行通信。通过ioctl&#xff0c;应用程序可以发送命令给设备驱动&#xff0c;控制设备的行为或获取设备的状态信息。…

再次梳理ISP的大致流程

前言&#xff1a; 随着智能手机的普及&#xff0c;相机与我们的生活越来越紧密相关。在日常生活中&#xff0c;我们只需要轻轻按下手机上的拍照按钮&#xff0c;就能记录下美好时刻。那么问题来了&#xff1a;从我们指尖按下拍照按钮到一张色彩丰富的照片呈现在我们面前&#x…

基于R语言森林生态系统的结构、功能与稳定性

在生态学研究中&#xff0c;森林生态系统的结构、功能与稳定性是核心研究内容之一。这些方面不仅关系到森林动态变化和物种多样性&#xff0c;还直接影响森林提供的生态服务功能及其应对环境变化的能力。森林生态系统的结构主要包括物种组成、树种多样性、树木的空间分布与密度…

nacos学习笔记(一)

1.前言 何为nacos&#xff0c;nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。可以说集注册中心&#xff0c;配置中心&#xff0c;服务管理于一起的平台。注册中心&#xff1a;相当于我们可以把服务注册到注册中心上&#xff0c;我们以后可以通过服…

在Java中实现集合排序

使用字面量的方式创建一个集合 //使用字面量的方式初始化一个List集合List<User> userList Arrays.asList(new User("小A",5),new User("小鑫",18),new User("小昌",8),new User("小鑫",8));注意&#xff1a;使用Arrays.asLis…

logback日志

一、使用两个以上spring环境变量做三目操作 <springProperty name"application_name" scope"context" source"spring.application.name"/><springProperty name"trace_app_name" scope"context" source"sprin…

mysql和redis的最大连接数

平时我们要评估mysql和redis的最大连接数&#xff0c;可以选择好环境&#xff08;比如4核8G&#xff09;,定好压测方法&#xff08;没有索引的mysql单表&#xff0c;redis单key&#xff09;进行压测&#xff0c;评估其最大并发量。 也可以查看各大云厂商的规格进行评估。 mys…

QEMU通过OVS实现联网

这篇笔记也是记录了一下自己的辛酸历程&#xff0c;仅供有需要的人参考。 首先关于qemu虚拟机的搭建&#xff0c;这不多赘述了&#xff0c;大家应该都会&#xff0c;这里可以给大家提供一个链接和一些命令。 QEMU搭建X86_64 Ubuntu虚拟系统环境https://blog.csdn.net/m0_531…

seleniun 自动化程序,python编程 我监控 chrome debug数据后 ,怎么获取控制台的信息呢

python 好的&#xff0c;使用 Python 来监控 Chrome 的调试数据并获取控制台信息&#xff0c;可以使用 websocket-client 库来连接 Chrome 的 WebSocket 接口。以下是一个详细的示例&#xff1a; 1. 安装必要的库 首先&#xff0c;你需要安装 websocket-client 库。可以使用…

IT面试求职系列主题-Jenkins

想成功求职&#xff0c;必要的IT技能一样不能少&#xff0c;先说说Jenkins的必会知识吧。 1) 什么是Jenkins Jenkins 是一个用 Java 编写的开源持续集成工具。它跟踪版本控制系统&#xff0c;并在发生更改时启动和监视构建系统。 2&#xff09;Maven、Ant和Jenkins有什么区别…

WEBRTC前端播放 播放器组件封装

组件封装 <template><div><div class"option"><input v-model"useStun" type"checkbox" /><label for"use-stun">Use STUN server</label></div><button click"startPlay"&g…

(五)ROS通信编程——参数服务器

前言 参数服务器在ROS中主要用于实现不同节点之间的数据共享&#xff08;P2P&#xff09;。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据&#xff0c;关…

攻防靶场(34):隐蔽的计划任务提权 Funbox1

目录 1. 侦查 1.1 收集目标网络信息&#xff1a;IP地址 1.2 主动扫描&#xff1a;扫描IP地址段 1.3 搜索目标网站 2. 初始访问 2.1 有效账户&#xff1a;默认账户 2.2 利用面向公众的应用 2.3 有效账户&#xff1a;默认账户 3. 权限提升 3.1 计划任务/作业&#xff1a;Cron 靶场…

嵌入式入门Day38

C Day1 第一个C程序C中的输入输出输出操作coutcin练习 命名空间使用方法自定义命名空间冲突问题 C对字符串的扩充C风格字符串的使用定义以及初始化C风格字符串与C风格字符串的转换C风格的字符串的关系运算常用的成员变量输入方法 布尔类型C对堆区空间使用的扩充作业 第一个C程序…

kubernetes第七天

1.影响pod调度的因素 nodeName 节点名 resources 资源限制 hostNetwork 宿主机网络 污点 污点容忍 Pod亲和性 Pod反亲和性 节点亲和性 2.污点 通常是作用于worker节点上&#xff0c;其可以影响pod的调度 语法&#xff1a;key[value]:effect effect:[ɪˈfek…