网络编程【InetAddress , TCP 、UDP 、HTTP 案例】
day38上
网络编程
InetAddress
理解:表示主机类
一个域名 对应 多个IP地址
public static void main(String[] args) throws UnknownHostException {//获取本机的IP地址
// InetAddress localHost = InetAddress.getLocalHost();
// System.out.println(localHost);//获取域名对应的服务器地址
// InetAddress byName = InetAddress.getByName("www.baidu.com");
// System.out.println(byName);//获取域名对应的所有的服务器地址InetAddress[] allByName = InetAddress.getAllByName("www.baidu.com");for (InetAddress inetAddress : allByName) {System.out.println(inetAddress);} }
//输出:www.baidu.com/183.2.172.42
// www.baidu.com/183.2.172.185
//是可以通过服务器地址如183.2.172.42去访问的
Scoket
Scoket也叫套接字,其表示的是IP地址和端口号的组合。
网络编程主要就是指Socket编程,网络间的通信其实就是Socket间的通信,数据就通过IO流在两个Scoket间进行传递。
TCP
API:Socket,ServerSocket
客户端(发送一个请求) 服务端(接收到这个请求,给予响应)
案例
1.简单的TCP通信
- 编写服务端程序
- 编写客户端程序
- 客户端向服务端发送请求信息,服务端成功接收
- 服务端向客户端发送响应信息,客户端成功接收
2.升级服务端,使其处理多个客户端请求
3.继续优化服务端,让多个客户端的请求无需排队
4.关闭资源-提取工具类
简单的TCP通信
简单的TCP通信理解图
TCP理解图
ps:奇男子去会所按摩
简单的TCP通信
前提:在同一局域网下
先运行服务器
//服务端
public class Server {public static void main(String[] args) throws IOException {//大堂经理ServerSocket server = new ServerSocket(8080);//18号技师//注意:accept()是线程阻塞的方法,该方法会等待客户端的连接成功后才生成一个Socket对象与之交互Socket socket = server.accept();//2.接受来自客户端的数据
// InputStream in = socket.getInputStream();
// InputStreamReader isr = new InputStreamReader(in, "GBK");
// BufferedReader br = new BufferedReader(isr);//一步步封装BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));String readLine = br.readLine();System.out.println(readLine);//3.向客户端发送数据PrintStream ps = new PrintStream(socket.getOutputStream());ps.println("18号技师:今年18岁");br.close();ps.close();server.close();}
}
使用println、BufferedReader
底层识别换行,BufferedReader流的readLine() – 读取一行
接收是获取的通过转换流再转带缓冲区的流,注意编码格式以防乱码
socket不能随便关闭,最后关闭或者不关闭
//客户端
public class Client {public static void main(String[] args) throws UnknownHostException, IOException {//注意:关闭流相当于关闭Socket!!!//奇男子Socket socket = new Socket("127.0.0.1", 8080);//1.向服务端发送数据PrintStream ps = new PrintStream(socket.getOutputStream());ps.println("奇男子:小妹妹,你多大了?");//4.接受来自服务端的数据BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));String readLine = br.readLine();System.out.println(readLine);ps.close();br.close();socket.close();}
}
简单TCP通信运行图
注意运行显示接受信息
传输文件
类似文件拷贝
较简单TCP通信,使用流不同
public class Server {public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(8080);Socket socket = server.accept();BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp4"));byte[] bs = new byte[1024];int len;while((len = bis.read(bs)) != -1){bos.write(bs, 0, len);}bis.close();bos.close();server.close();}
}
//读取写入文件
public class Client {public static void main(String[] args) throws UnknownHostException, IOException {Socket socket = new Socket("127.0.0.1", 8080);BufferedInputStream bis = new BufferedInputStream(new FileInputStream("奇男子.mp4"));//直接输出流转换为带有缓冲区的,效率更高BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());byte[] bs = new byte[1024];int len;while((len = bis.read(bs)) != -1){bos.write(bs, 0, len);}bis.close();bos.close();socket.close();}
}
//读取源文件写出
单聊
单聊
把流放在循环外面,防止每次次循环都new一个流,浪费资源,还有就是没有关闭资源
一对一,你一言我一语
public class Server {public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(8080);Socket socket = server.accept();Scanner scan = new Scanner(System.in);BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));PrintStream ps = new PrintStream(socket.getOutputStream());while(true){String readLine = br.readLine();System.out.println(readLine);ps.println("18号技师:" + scan.next());}}
}
public class Client {public static void main(String[] args) throws UnknownHostException, IOException {Socket socket = new Socket("127.0.0.1", 8080);Scanner scan = new Scanner(System.in);PrintStream ps = new PrintStream(socket.getOutputStream());BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));while(true){ps.println("奇男子:" + scan.next());String readLine = br.readLine();System.out.println(readLine);}}
}
优化
单聊一言一语改进:用多线程,一个线程发送、一个线程接受
改进后一个人可以发多条消息
public class Server {public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(8080);Socket socket = server.accept();//接收消息new ReceiveThread(socket).start();//发送消息Scanner scan = new Scanner(System.in);PrintStream ps = new PrintStream(socket.getOutputStream());while(true){ps.println("18号技师:" + scan.next());}}
}
public class Client {public static void main(String[] args) throws UnknownHostException, IOException {Socket socket = new Socket("127.0.0.1", 8080);//接收消息new ReceiveThread(socket).start();//发送消息Scanner scan = new Scanner(System.in);PrintStream ps = new PrintStream(socket.getOutputStream());while(true){ps.println("奇男子:" + scan.next());}}
}
添加一个接受消息的线程
//接受的线程
public class ReceiveThread extends Thread{private Socket socket;public ReceiveThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));while(true){String readLine = br.readLine();System.out.println(readLine);}} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}
群聊
多线程,发送在子线程,接受在主线程
设想是几个客户端之间互相发送消息,但由于这里使用TCP,而(面向连接)TCP必须通过服务端进行交流,不能这么操作
TCP群聊理解图
服务端连接成功一个就会产生一个Socket,ServerSocket不算进去
这里接受当前客户端的消息再发送给其他客户端,key就直接做成输出流,而不是Socket对象
客户端没有问题,就直接用Client、ReceiveThread,服务端需要更改
简单测试需要多个电脑操作进行群聊,即多个客户端
public class Server {public static final ConcurrentHashMap<String, PrintStream> map = new ConcurrentHashMap<>();public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(8080);while(true){Socket socket = server.accept();String ip = socket.getInetAddress().toString();PrintStream ps = new PrintStream(socket.getOutputStream());map.put(ip, ps);new ServerThread(socket).start();}}
}
添加一个服务端的线程
public class ServerThread extends Thread{private Socket socket;public ServerThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {//接受当前客户端的消息BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));while(true){String readLine = br.readLine();System.out.println(readLine);//发送给其他客户端消息Set<Entry<String,PrintStream>> entrySet = Server.map.entrySet();for (Entry<String, PrintStream> entry : entrySet) {String ip = entry.getKey();PrintStream ps = entry.getValue();if(!socket.getInetAddress().toString().equals(ip)){ps.println(readLine);}}}} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}
三次握手、四次挥手
UDP
简介
UDP(User Datagram Protocol)用户数据报包协议,UDP和TCP位于同一层-传输层,但它对于数据包的顺序错误或重发没有TCP可靠;UDP是一种面向无连接的通信协议。UDP向应用程序提供一种发送封装的原始IP数据报的方法,并且发送时无需建立连接,不保证可靠数据的传输
UDP理解图
适用:视频聊天
简单的UDP通信
协议的Socket是DatagramSocket
trim()去首尾空格,因为传的数据不到容量就会是空白,超过容量也接收不了
public class Client01 {public static void main(String[] args) throws IOException {//注意:7070表示的是自己的端口号,不是对方的端口号DatagramSocket socket = new DatagramSocket(7070);//1.向客户端2发送数据byte[] buf = "小桥流水人家".getBytes();DatagramPacket p = new DatagramPacket(buf , 0, buf.length, InetAddress.getByName("127.0.0.1"), 8080);socket.send(p);//4.接受来自客户端1的数据buf = new byte[1024];p = new DatagramPacket(buf , buf.length);socket.receive(p);System.out.println(new String(buf).trim());socket.close();}
}
public class Client02 {public static void main(String[] args) throws IOException {DatagramSocket socket = new DatagramSocket(8080);//2.接受来自客户端1的数据byte[] buf = new byte[1024];DatagramPacket p = new DatagramPacket(buf , buf.length);socket.receive(p);System.out.println(new String(buf).trim());//3.向客户端2发送数据buf = "古道西风瘦马".getBytes();p = new DatagramPacket(buf , 0, buf.length, InetAddress.getByName("127.0.0.1"), 7070);socket.send(p);socket.close();}
}
单聊
客户端之间发送消息
public class Client01 {public static void main(String[] args) throws SocketException {DatagramSocket socket = new DatagramSocket(7070);new ReceiveThread(socket).start();new SendThread("奇男子", "127.0.0.1", 8080, socket).start();}
}
public class Client02 {public static void main(String[] args) throws SocketException {DatagramSocket socket = new DatagramSocket(8080);new ReceiveThread(socket).start();new SendThread("小小", "127.0.0.1", 7070, socket).start();}
}
添加一个发送线程、一个接收线程
public class SendThread extends Thread{private String nickName;private String ip;private int port;private DatagramSocket socket;public SendThread(String nickName, String ip, int port, DatagramSocket socket) {this.nickName = nickName;this.ip = ip;this.port = port;this.socket = socket;}@Overridepublic void run() {Scanner scan = new Scanner(System.in);while(true){byte[] buf = (nickName + ":" + scan.next()).getBytes();try {DatagramPacket p = new DatagramPacket(buf, buf.length, InetAddress.getByName(ip), port);socket.send(p);} catch (IOException e) {e.printStackTrace();}}}}
public class ReceiveThread extends Thread{private DatagramSocket socket;public ReceiveThread(DatagramSocket socket) {this.socket = socket;}@Overridepublic void run() {while(true){byte[] buf = new byte[1024];DatagramPacket p = new DatagramPacket(buf , buf.length);try {socket.receive(p);System.out.println(new String(buf).trim());} catch (IOException e) {e.printStackTrace();}}}
}
TCP vs UDP
TCP | UDP | |
---|---|---|
是否连接 | 面向连接 | 无面向连接 |
传输可靠性 | 可靠 | 不可靠 |
应用场合 | 传输大量数据 | 少量数据 |
速度 | 慢 | 快 |
UDP — 发短信
TCP — 打电话
HTTP
查询淘宝商品
需求:获取淘宝商品周边类别
市面上服务器一般都默认为utf-8,设置编码格式,解决乱码
public class Test01 {public static void main(String[] args) throws IOException {String path = "https://suggest.taobao.com/sug?code=utf-8&q=%E8%80%90%E5%85%8B&callback=cb";//创建链接对象URL url = new URL(path);//获取连接对象//玩的是他的子类,父类为抽象类HttpURLConnection connection = (HttpURLConnection) url.openConnection();//设置参数connection.setConnectTimeout(5000);//设置连接超时时间connection.setReadTimeout(5000);//设置读取数据超时时间connection.setDoInput(true);//设置是否允许使用输入流connection.setDoOutput(true);//设置是否允许使用输出流//获取响应状态码int code = connection.getResponseCode();if(code == HttpURLConnection.HTTP_OK){BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));char[] cs = new char[1024];int len;while((len = br.read(cs)) != -1){System.out.println(new String(cs, 0, len));}}else if(code == HttpURLConnection.HTTP_NOT_FOUND){System.out.println("页面未找到");}}
}
下载图片
更改流即可【不同数据源用不同的流即可】
public class Test02 {public static void main(String[] args) throws IOException {String path = "https://wx2.sinaimg.cn/mw690/e2438f6cly1hoo3qpm7vrj21111jk4mn.jpg";//创建链接对象URL url = new URL(path);//获取连接对象HttpURLConnection connection = (HttpURLConnection) url.openConnection();//设置参数connection.setConnectTimeout(5000);//设置连接超时时间connection.setReadTimeout(5000);//设置读取数据超时时间connection.setDoInput(true);//设置是否允许使用输入流connection.setDoOutput(true);//设置是否允许使用输出流//获取响应状态码int code = connection.getResponseCode();if(code == HttpURLConnection.HTTP_OK){BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("金智媛.jpg"));byte[] bs = new byte[1024];int len;while((len = bis.read(bs)) != -1){bos.write(bs, 0, len);}bis.close();bos.close();}else if(code == HttpURLConnection.HTTP_NOT_FOUND){System.out.println("页面未找到");}}
}
所需学习类
DatagramPacket —此类表示数据报包
DatagramSocket —此类用来发送和接受数据报包的套接字
SocketAddress
getLocalSocketAddress
()
返回此套接字绑定的端点的地 址,如果尚未绑定则返回null
。
Void
send(
DatagramPacketp)
从此套接字发送数据报包。
Void
receive(
DatagramPacketp)
从此套接字接收数据报包。SocketAddress —抽象类,IP+端口号
总结
1.网络编程
1.1 InetAddress
1.2 TCP
传输文件
单聊、优化单聊
群聊
三次握手、四次挥手
1.3 UDP
单聊
TCP vs UDP
1.4 HTTP
查询淘宝商品
下载图片
相关文章:

网络编程【InetAddress , TCP 、UDP 、HTTP 案例】
day38上 网络编程 InetAddress 理解:表示主机类 一个域名 对应 多个IP地址 public static void main(String[] args) throws UnknownHostException {//获取本机的IP地址 // InetAddress localHost InetAddress.getLocalHost(); // System.out.println(localHos…...

软考中级工程师网络技术第二节网络体系结构
OSPF将路由器连接的物理网络划分为以下4种类型,以太网属于(25),X.25分组交换网属于(非广播多址网络NBMA)。 A 点对点网络 B 广播多址网络 C 点到多点网络 D 非广播多址网络 试题答案 正确答案: …...

Mac 软件清单
~自留备用~ Macbook用了几年之后, 512G的内置硬盘有些紧张了, 这几天总是提示空间不足, 就重装了下系统, 重装之后竟然不记得有些软件的名字和下载链接, 特此记录 Office 办公套件 直接从微软官网下载Office 安装包https://officecdnmac.microsoft.com/pr/C1297A47-86C4-4C1F…...

【Leetcode每日一题】 分治 - 颜色分类(难度⭐⭐)(57)
1. 题目解析 题目链接:75. 颜色分类 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 算法思路解析 本算法采用三指针法,将数组划分为三个区域,分别用于存放值为0、1和2的元素。通过…...

微信登录功能-保姆级教学
目录 一、使用组件 二、登录功能 2.1 步骤 2.2 首先找到网页权限 复制demo 代码 这里我们需要修改两个参数 三、前端代码 3.1 api 里weiXinApi.ts 3.2 api里的 index.ts 3.3 pinia.ts 3.4 My.vue 四、后端代码 4.1 WeiXinController 4.2 Access_Token.Java 4.3 We…...

嵌入式MCU BootLoader开发配置详细笔记教程
目录 一、BootLoader基础 二、BootLoader原理及配置 三、BootLoader程序 bootloader.h bootloader.c 四、Application1 用户程序 application1.h application1.c 五、Application2 用户程序 application2.h 六、程序运行效果 七、工程文件Demo 一、BootLoader基础 …...

Unity 中消息提醒框
Tooltip 用于ui布局 using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.UI;[ExecuteInEditMode()] // 可以在编辑模式下运行public class Tooltip : MonoBehaviour {public TMP_Text header; // 头部文本publi…...
好数(蓝桥杯)
文章目录 好数题目描述暴力方法一暴力方法二(超时) 好数 题目描述 【问题描述】 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位 )上的数字是奇数,偶数位(十位、千位、十万位 …...

自动化收集Unity版本更新日志
自动化收集Unity版本更新日志 🍥功能介绍🥪食用手册填写配置开始搜集 🍨数据展示 🍥功能介绍 💡获取指定年份中所有的Unity版本更新日志。 💡根据指定字符串过滤。 💡.收集后自动保存成markdow…...
【CSS】CSS水平居中方案
CSS水平居中方案 1. 行内元素水平居中 设置父元素的text-align:center .box {width: 300px;height: 300px;margin: 100px auto;text-align: center;background-color: pink; }2. 块级元素水平居中 当块级元素设置了明确的宽度数值时,可以使用margin: 0 auto 3.…...

SQL注入sqli_labs靶场第二题
解题思路与第一题相同 ?id1 and 11 和?id1 and 12进行测试如果11页面显示正常和原页面一样,并且12页面报错或者页面部分数据显示不正常,那么可以确定此处为数字型注入。 联合查询: 猜解列名数量:3 ?id1 order by 4 判断回显…...

基于机器学习的人脸发型推荐算法研究与应用实现
1.摘要 本文主要研究内容是开发一种发型推荐系统,旨在识别用户的面部形状,并根据此形状推荐最适合的发型。首先,收集具有各种面部形状的用户照片,并标记它们的脸型,如长形、圆形、椭圆形、心形或方形。接着构建一个面部…...

【服务器部署篇】Linux下Nginx的安装和配置
作者介绍:本人笔名姑苏老陈,从事JAVA开发工作十多年了,带过刚毕业的实习生,也带过技术团队。最近有个朋友的表弟,马上要大学毕业了,想从事JAVA开发工作,但不知道从何处入手。于是,产…...
React搭建一个文章后台管理系统
1、项目准备 本篇文章讲解的是一个简单的文章后台管理系统,系统的功能很简单,如下:登录、退出;首页;内容(文章)管理:文章列表、发布文章、修改文章。 1)React官方脚手架:create-rea…...
Elasticsearch 支持的插件 —— 筑梦之路
Analysis 插件: 1、IK Analyzer:适用于中文分词的插件,提供了针对中文文本的分析器。 2、Smart Chinese Analysis:另一个中文分词插件,支持中文智能分词。 集群管理插件: 1、Kibana:Elasticsear…...
HTML:链接
目录 一、超链接 二、 外联元素 一、<a>超链接 <a> 标签用于定义超链接,超链接可以让用户从一个网页跳转到另一个网页。 常用属性: href指定链接的目标地址。download表示链接是一个下载链接,指定下载的文件名。target 指定在…...

vscode远程连接centos
文章目录 vacode连接linux1. 安装插件2. 查看配置3. 打开ssh4. 远程连接 vacode连接linux 1. 安装插件 在扩展栏搜索remote ,找到Remote Development插件,进行安装: 2. 查看配置 打开自己的linux终端,输入ifconfig,…...
scala---面向对象(类,对象,继承,抽象类,特质)
一、类(class)和 对象(object) 1、类 类就是对客观的一类事物的抽象。用一个class关键字来描述和Java一样,在这个类中可以拥有这一类事物的属性,行为等等。 2、为什么要有对象 在java中的一个class既可…...
【机器学习300问】68、随机初始化神经网络权重的好处?
一、固定的初始化神经网络权重可能带来的问题 在训练神经网络的时候,初始化权重如果全部设置为0或某个过大值/过小值。会导致一些问题: 对称权重问题:全为0的初始化权重会导致神经网络在前向传播时接收到的信号输入相同。每个神经网络节点中…...

数据结构与算法——20.B-树
这篇文章我们来讲解一下数据结构中非常重要的B-树。 目录 1.B树的相关介绍 1.1、B树的介绍 1.2、B树的特点 2.B树的节点类 3.小结 1.B树的相关介绍 1.1、B树的介绍 在介绍B树之前,我们回顾一下我们学的树。 首先是二叉树,这个不用多说ÿ…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...