网络编程【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通信

  1. 编写服务端程序
  2. 编写客户端程序
  3. 客户端向服务端发送请求信息,服务端成功接收
  4. 服务端向客户端发送响应信息,客户端成功接收

2.升级服务端,使其处理多个客户端请求

3.继续优化服务端,让多个客户端的请求无需排队

4.关闭资源-提取工具类

简单的TCP通信
简单的TCP通信理解图

TCP理解图

ps:奇男子去会所按摩
简单的TCP通信理解图

简单的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对象

TCP群聊理解图

客户端没有问题,就直接用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理解图

简单的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

TCPUDP
是否连接面向连接无面向连接
传输可靠性可靠不可靠
应用场合传输大量数据少量数据
速度

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

Voidsend(DatagramPacket p) 从此套接字发送数据报包。

Voidreceive(DatagramPacket p) 从此套接字接收数据报包。

SocketAddress —抽象类,IP+端口号

总结

1.网络编程
1.1 InetAddress
1.2 TCP
传输文件
单聊、优化单聊
群聊
三次握手、四次挥手
1.3 UDP
单聊
TCP vs UDP
1.4 HTTP
查询淘宝商品
下载图片

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

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

相关文章

Mac 软件清单

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

python botos s3 aws

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html AWS是亚马逊的云服务&#xff0c;其提供了非常丰富的套件&#xff0c;以及支持多种语言的SDK/API。本文针对其S3云储存服务的Python SDK&#xff08;boto3&#xff09;的使用进行介绍。 …

golang 使用栈模拟计算器

思路&#xff1a; // Author sunwenbo // 2024/4/12 16:51 package mainimport ("errors""fmt""strconv" )// 使用数组来模拟一个栈的应用 type Stack struct {MaxTop int //表示栈最大可以存放数的个数Top int //表示栈底&#xff…

了解 Vue 工程化开发中的组件通信

目录 1. 组件通信语法 1.1. 什么是组件通信&#xff1f; 1.2. 为什么要使用组件通信&#xff1f; 1.3. 组件之间有哪些关系&#xff08;组件关系分类&#xff09;&#xff1f; 1.4. 组件通信方案有哪几类 &#xff1f; 2. 父子通信流程图 3. 父传子 3.1. 父传子核心流程…

Tool:VRAM的简介、查询电脑VRAM的常用方法

Tool&#xff1a;VRAM的简介、查询电脑VRAM的常用方法 目录 VRAM的简介 查询电脑VRAM的常用方法 1、对于Windows系统 T1、设置-系统-显示查询法 T2、使用 DirectX 诊断工具&#xff1a; T3、使用系统信息工具&#xff1a; 2、对于Linux系统 T1、使用nvidia-smi命令&…

网络网络层之(2)ARP协议

网络网络层之(2)ARP协议 Author&#xff1a;Once Day Date: 2024年4月1日 漫漫长路&#xff0c;有人对你笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的博客-CSDN博客。 参考文档: 《TCP/IP详解卷一》arp(8) - Linux manual page (man7.org)彻底搞懂系…

Android MTK 屏下指纹的调试过程记录

Demo链接 -----> https://download.csdn.net/download/u011694328/89118346 一些品牌手机都有了屏下指纹的功能&#xff0c;还算是个比较新颖的功能&#xff0c;最近有项目需要使用屏下指纹&#xff0c; 使用的是汇顶&#xff08;Goodix&#xff09;的指纹方案&#xff0c…

<计算机网络自顶向下> TCPUDP套接字编程

应用实现&#xff1a;源端的应用进程交换报文实现应用协议&#xff0c;来实现各种各样的网络应用&#xff08;dash&#xff0c;email, etc&#xff09; 而应用层通信不可以直接通信&#xff0c;需要借助下层的服务才可以进行&#xff0c;通过层间接口交给下层&#xff0c;通过…

系统架构最佳实践 -- 金融企业的资损防控

一、资损产生的原因 由于支付行业的特殊性与复杂性&#xff08;主要处理资金相关业务&#xff09;&#xff0c;支付公司处于资损的风口浪尖&#xff0c;最容易发生资损&#xff0c;可以说资损风险无处不在。 常规来说&#xff0c;资损原因主要可以分为以下三类&#xff1a; 1…

【MATLAB源码-第49期】基于蚁群算法(ACO)算法的栅格路径规划,输出最佳路径图和算法收敛曲线图。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 蚁群算法是一种模拟自然界蚂蚁觅食行为的启发式优化算法。在蚁群系统中&#xff0c;通过模拟蚂蚁之间通过信息素沟通的方式来寻找最短路径。 在栅格路径规划中&#xff0c;蚁群算法的基本步骤如下&#xff1a; 1. 初始化: …

Notepad++软件安装及配置说明

Notepad是 Windows操作系统下的一套文本编辑器&#xff0c;有完整的中文化接口及支持多国语言编写的功能。 Notepad功能比 Windows自带记事本强大&#xff0c;除了可以用来制作一般的纯文字说明文件&#xff0c;也十分适合编写计算机程序代码。Notepad不但可以显示行号&#xf…

鸿蒙开发快速入门

基本概念 ArkTS 因为ArkTS是基于Type Script扩展而来&#xff0c;是Type Script的超集&#xff0c;所以也可以关注一下Type Script的语法来理解ArkTS的语法 ArkUI HarmonyOS提供了一套UI开发框架&#xff0c;即方舟开发框架&#xff08;ArkUI框架&#xff09;。方舟开发框架…

对常见FTP客户端/服务器的调查与分析

前言 主要是想看看常见的服务器和客户端是如何实现协议中要求的功能的&#xff0c;。 比如RF959要求的记录结构&#xff08;Record Structure&#xff09;、页结构&#xff08;Page Structure&#xff09;、Block Mode、Compress Mode&#xff0c;看起来就很抽象。 实测发现…

给自己的机器人部件安装单目摄像头并实现gazebo仿真功能

手术执行器添加摄像头 手术执行器文件夹surgical_new内容展示如何添加单目摄像头下载现成的机器人环境文件启动仿真环境 手术执行器文件夹surgical_new内容展示 进入src文件夹下选择进入vision_obliquity文件夹 选择launch 有两个可用gazebo中rviz展示的launch文件&#xff0…

Unity 2D让相机跟随角色移动

相机跟随移动 最简单的方式通过插件Cinemachine 在窗口/包管理器选择全部找到Cinemachine&#xff0c;导入。然后在游戏对象/Cinemachine创建2D Camera。此时层级中创建一个2D相机。选中人物拖入检查器Follow。此时相机跟随人物移动。 修改相机视口距离 在检查器中Lens下调正…

c++11 标准模板(STL)本地化库 - 平面类别(std::codecvt) - 在字符编码间转换,包括 UTF-8、UTF-16、UTF-32 (四)

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 在字符编码间转换&#xff0c;包括 UTF-8、UTF-16、UTF-32 std::…

MES生产管理系统:私有云、公有云与本地化部署的比较分析

随着信息技术的迅猛发展&#xff0c;云计算作为一种新兴的技术服务模式&#xff0c;已经深入渗透到企业的日常运营中。在众多部署方式中&#xff0c;私有云、公有云和本地化部署是三种最为常见的选择。它们各自具有独特的特点和适用场景&#xff0c;并在不同程度上影响着企业的…

python应用-os库操作目录

python自带的os模块提供了许多与操作系统交互的函数&#xff0c;适配多种操作系统&#xff0c;比如windows&#xff0c;mac&#xff0c;linux等&#xff0c;比如常用路径操作、进程管理、环境参数等都可通过os模块实现。 以下是自带的os.py中的前面一部分代码。 第一个红框中主…

kibana源码编译

一、安装nodejs16.14.2及yarn &#xff08;一&#xff09;nodejs 1、下载 https://cdn.npmmirror.com/binaries/node/v16.14.2/node-v16.14.2-linux-x64.tar.gz2、解压 tar -zxf node-v16.14.2-linux-x64.tar.gz -C /app cd /app mv node-v16.14.2-linux-x64 node3、配置环…