网络编程【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.hqwc.cn/news/618949.html

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

相关文章

专业140+总分410+北京理工大学826信号处理导论考研经验北理工电子信息通信工程,真题,参考书,大纲。

今年考研专业课826信号处理导论&#xff08;信号系统和数字信号处理&#xff09;140&#xff0c;总分410&#xff0c;顺利上岸&#xff01;回看去年将近一年的复习&#xff0c;还是记忆犹新&#xff0c;有不少经历想和大家分享&#xff0c;有得有失&#xff0c;希望可以对大家复…

Hadoop概述及集群搭建

文章目录 一、Hadoop介绍二、Hadoop发展简史三、Hadoop核心组件四、Hadoop架构变迁1、Hadoop 1.02、Hadoop 2.03、Hadoop 3.0 五、Hadoop集群简介六、Hadoop部署模式七、Hadoop 集群搭建第一步&#xff1a;创建虚拟机第二步&#xff1a;安装Linux镜像第三步&#xff1a;网络配置…

51单片机实验03-单片机定时/计数器实验

目录 一、实验目的 二、实验说明 1、51单片机有两个16位内部计数器/定时器&#xff08;C/T&#xff0c; Counter/Timer&#xff09;。 2、模式寄存器TMOD 1) M1M0工作模式控制位&#xff1b; 2) C/T定时器或计数器选择位&#xff1a; 3&#xff09;GATE定时器/计数器运行…

云计算:Linux 部署 OVN 集群

目录 一、实验 1.环境 2.Linux 部署 OVN 集群&#xff08;中心端&#xff09; 3.Linux 部署 OVN 集群&#xff08;业务端1&#xff09; 4.Linux 部署 OVN 集群&#xff08;业务端2&#xff09; 4.OVN 中心端 连接数据库 5.OVN 业务端1 加⼊控制器 6.OVN 业务端2 加⼊控…

为什么光伏探勘测绘需要无人机?

随着全球对可再生能源需求的不断增长&#xff0c;光伏产业也迎来了快速发展的机遇。光伏电站作为太阳能发电的主要形式之一&#xff0c;其建设前期的探勘测绘工作至关重要。在这一过程中&#xff0c;无人机技术的应用正逐渐展现出其独特的优势。那么&#xff0c;为什么光伏探勘…

Mac 软件清单

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

使用LangChain和GPT-4,创建Pandas DataFrame智能体

大家好&#xff0c;数据分析和数据处理是数据科学领域每天都在进行的基本任务。高效和快速的数据转换对于提取有意义的见解和基于数据做出明智决策至关重要。其中最受欢迎的工具之一是Python库Pandas&#xff0c;它提供了一个功能强大的DataFrame工具&#xff0c;使用灵活直观的…

编曲知识19:自动化处理 发送原理 混响 延迟

自动化处理 发送原理 混响 延迟小鹅通-专注内容付费的技术服务商https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_661a68eae4b023c0a96a8b36?course_id=course_2XLKtQnQx9GrQHac7OPmHD9tqbv 自动化处理 自动化 鼠标挪动到轨道左下角打开自动化轨道 或右键轨道-左键单击…

001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂

001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂 文章目录 001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂创作背景通信模型ISO/OSI七层模型 和 TCP/IP四层模型网络通信数据包格式&#xff08;Ethernet II&…

数据库:SQL分类之DQL详解

1.DQL语法 select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后条件列表 order by 排序字段列表 limit 分页参数 基本查询 条件查询&#xff08;where&#xff09; 聚合函数&#xff08;count、max、min、avg、sum &#xff09; 分组查询&…

模型预测控制MPC(1)—— 基础概念

文章目录 1. 历史沿革1.1 控制论1.2 自动控制与强化学习 2. 模型预测控制 1. 历史沿革 我本科做机器人的时候接触过一点自动控制&#xff0c;主要做了大量 PID 在嵌入式控制系统的应用&#xff1b;硕士期间研究方向是强化学习。在我调研 MPC 的过程中&#xff0c;发现它同时出…

计算机视觉——手机目标检测数据集

这是一个手机目标检测的数据集&#xff0c;数据集的标注工具是labelimg,数据格式是voc格式&#xff0c;要训练yolo模型的话&#xff0c;可以使用脚本改成txt格式&#xff0c;数据集标注了手机&#xff0c;标签名&#xff1a;telephone,数据集总共有1960张&#xff0c;有一部分是…