22-05-05 西安 javaSE(18) 网络编程、TCP\IP、Socket通信
MAC与IP地址
MAC地址
每一块网卡带有的ROM(只读存储器)中,都预先烧录了一个唯一的MAC地址。
MAC地址=制造厂商编号+产品编号
所以世界上每一个MAC地址都是独一无二的
IP地址
在互联网中,一个IP地址用于唯一标识一个网络接口(Network Interface)
通过ip地址可以轻松对计算机进行分组管理,通常把ip中表示分组部分的称为“网络地址”,表示组内各台计算机的部分称为“主机地址”
ip地址以圆点分隔号的四个十进制数字表示,每个数字从0到255
IP地址 = 网络地址 + 主机地址(又称:主机号和网络号组成)
子网掩码
子网掩码的作用:标识出32比特的IP地址中,从哪一位到哪一位是网络地址,从哪一位到哪一位是主机地址。
左边连续的1的个数代表网络号的长度(使用时必须是连续的),右边连续的0的个数代表主机号的长度。
- 网络号相同的主机称之为本地网络,本地网络中的主机可以直接相互通信
- 网络号不相同的主机称之为远程网络主机,远程网络中的主机要相互通信必须通过本地网关(Gateway)来传递转发数据。
网络号相同的主机处于同一个网段,网关(Gateway)就是到其他网段的出口。
ARP地址解析协议
ARP 地址解析协议:用于实现IP地址到MAC地址的转换
ARP工作方式:
会用广播方式对LAN内所有的计算机提问,“有谁的IP地址是XXX.XXX.XX.XX”吗,有的话请把你的MAC地址告诉我。
ARP缓存表
当向各个计算机都问完一轮之后,ARP会把得到的MAC地址和IP地址关系缓存起来(内存)
arp -a //查看arp缓存表内容
DHCP服务器
DHCP:动态主机设置协议
dhcp服务器上记录着可以被分配到LAN内计算机的IP地址范围和子网掩码的值。
可以手动设置ip地址和子网掩码,但是大多数情况下还是选择“自动获得ip地址”,这个选项会使计算机在启动时去DHCP服务器获取ip地址和子网掩码,并自动配置它们
默认网关
通常会把路由器的ip地址设置为默认网关。也就是说路由器是从LAN通往互联网世界的入口。
域名解析
使用域名访问过程
当我们使用域名访问某一个网站时,实际上就是将请求包(以Http请求为例)通过网络传输给某台服务器,比如访问域名“www.baidu.com”时:
域名解析服务器 DNS 负责把域名翻译成对应的 IP,客户端再根据 IP 地址访问服务器
有一个特殊的本机域名 localhost ,它对应的 IP 地址总是本机地址 127.0.0.1 。
DNS系统
域名解析是由DNS系统来负责的,DNS服务接受外部请求,从请求里提取域名。再拿着这个域名去做下面这俩件事,
- 将一个域名解析为一个IP地址
- 将一个域名解析为另外一个域名(CNAME别名)
最终返回一个IP地址给发送者。发送者拿到IP地址之后,才去完成真正的请求调用。
可以想象为Java里Map来表示这个关系:{域名:IP}。
HOSTS系统文件
文件地址:C:\WINDOWS\system32\drivers\etc\hosts
作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”
用户在浏览器中输入url,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页。
如果没有找到,则系统再会将网址提交DNS域名解析服务器进行IP地址的解析,如果发现是被屏蔽的IP或域名,就会禁止打开此网页!
防火墙
TCP/IP
TCP/IP协议
TCP/IP协议【理解1】
- IP 协议只负责发数据包,不保证顺序和正确性
- TCP 协议负责控制数据包传输,它在传输数据之前需要先建立连接,建立连接后才能传输数据,传输完后还需要断开连接。
TCP/IP协议【理解2】
- IP 协议位于网络层,负责将数据包从源主机路 由到目标主机;
- TCP 协议位于传输层,负责在源主机和目标主机之间建立可靠的连接并确保数据的有序传输。
四层网络模型
将网络模型分为4层,应用层、传输层、网络层和网络接口层(链路层)
TCP/IP协议:协议是水平的,是控制对等实体之间通信的规则的。服务是下层对上层通过层间接口提供的
网络接口层:
负责数据帧的发送和接收
-------------------------------------------------网络层
通过路由算法使得数据报独立到达目的地 网络层来看,通信的俩端是俩个主机,实际上是俩个主机的应用进程相互通信。
IP 协议:IP 协议位于网络层,IP 协议只负责发数据包,不保证顺序和正确性
----------------------------------------------------
传输层
套接字socket=ip地址+端口号,在网络上唯一标识了传输层的一个通信端口。
传输层在计算机之间提供端到端的通信,端点就是主机中的应用进程。端口标识了应用层中不同的进程。 传输层分为2种传输协议tcp和udp,分别用来满足传输不同性质应用层的需要
TCP 协议:TCP 协议位于传输层,负责在源主机和目标主机之间建立可靠的连接并确保数据的有序传输。
-----------------------------------------------------------
应用层
文件传送协议:ftp 远程登录协议:telnet 邮件传输协议:smtp 超文本传输协议:http
UDP协议
UDP 协议(User Datagram Protocol)是一种数据报文协议,它是无连接协议,不保证可靠传输。因为 UDP 协议在通信前不需要建立连接,因此它的传输效率比 TCP 高,
发送端和接收端
- 将数据、源、目的封装成数据包,不需要建立连接
- 每个数据报的大小限制在64K内
- 因无需连接,故是不可靠的
- 发送数据结束时无需释放资源,速度快
ping 与 telnet
同事给我的,NetAssist.exe 网络调试工具
TCP(传输控制)协议
面向连接(三次握手、四次挥手)
面向连接的服务是一种可靠的服务,整个连接生存周期包括3个阶段(建立连接、数据传输、释放连接)
为了保证传输连接的可靠建立与释放,TCP使用了三次握手。
TCP虚电路
TCP流量控制(滑动窗口)
TCP拥塞控制
TCP报文段
传输层所传输的数据报称为传输协议数据单元(TPDU)。根据协议不同分为TCP报文段和UDP数据报,UDP数据报也称为用户数据报。
TCP报文段分为俩部分,前面是报头,后面是数据。
TCP报文的布局
每个字段的意义:
TCP洪范攻击
TCP复用和分用
客户端和服务端
- 使用TCP协议前,须先建立TCP连接,形成传输数据通道
- 传输前,采用“三次握手”方式,是可靠的
- 在连接中可进行大数据量的传输
- 传输完毕,需释放已建立的连接,效率低
- 优点:可靠,安全,但是效率低。【每一次发送数据都要服务端确认】
网络编程
网络编程要素
网络编程:在网络间完成数据的传输,相比于IO流在本地完成数据的传输
网络编程要素
- 如何准确地定位网络上一台或多台主机【ip】
- 找到主机后如何可靠高效地进行数据传输。【协议】
java.net.InetAddress
- InetAddress.getLocalHost() 获取本地ip对应的InetAddress实例
- String getHostAddress() 返回该InetAddress实例对应的ip地址字符串
//获取本机ip
public static void main(String[] args) {try {//打印流 打印本机ipSystem.out.println(InetAddress.getLocalHost().getHostAddress());} catch (UnknownHostException e) {e.printStackTrace();}
}
唯一标识 Internet 上的计算机,InetAddress类主要表示IP地址
- InetAddress.getByName() 根据主机名获取对应的InetAddress实例
- String getHostAddress() 获取InetAddress实例对应的ip地址字符串
public static void main(String[] args) throws UnknownHostException {//根据主机名获取对应的InetAddress实例InetAddress inetAddress = InetAddress.getByName("www.baidu.com");//获取InetAddress实例域名System.out.println(inetAddress.getHostName());//获取InetAddress实例ip地址System.out.println(inetAddress.getHostAddress());//获取InetAddress实例ip地址的全限定域名System.out.println(inetAddress.getCanonicalHostName());
}
ip地址的全限定域名??
DatagramSocket与DatagramPacket
java.net.DatagramPacket
系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
public class FileTest {//UDP发送端@Testpublic void client() throws IOException {//使用UDP协议传输DatagramSocket datagramSocket = new DatagramSocket();byte[] bytes="我在精神病院学斩神".getBytes(StandardCharsets.UTF_8);//DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)//构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。DatagramPacket p=new DatagramPacket(bytes,0,bytes.length, InetAddress.getByName("127.0.0.1"),9898);datagramSocket.send(p);datagramSocket.close();}//UDP接收端@Testpublic void server() throws IOException {//使用UDP协议传输DatagramSocket datagramSocket = new DatagramSocket(9898);byte[] bytes=new byte[1024];//DatagramPacket(byte[] buf, int length)//构造 DatagramPacket,用来接收长度为 length 的数据包。DatagramPacket p=new DatagramPacket(bytes,bytes.length);datagramSocket.receive(p);System.out.println(new String(p.getData(),0,p.getData().length));datagramSocket.close();}
}
java.net.URL
URL(Uniform Resource Locator):统一资源定位符,它表示 Internet 上某一资源的地址。
URL的基本结构由5部分组成:
<传输协议>://<主机名>:<端口号>/<文件名>
例如: http://192.168.1.100:8080/helloworld/index.jsp
构造器:
URL(String spec)
根据 String 表示形式创建 URL 对象。
方法:
public final InputStream openStream() throws IOException
打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。此方法是下面方法的缩写: openConnection().getInputStream()
public URLConnection openConnection() throws IOException
返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。
//获取整个url结构
一个URL对象生成后,其属性是不能被改变的,但可以通过它给定的方法来获取这些属性
public String getProtocol( ) ;//URL的协议名
public String getHost( ) ;//该URL的主机名
public String getPort( ) ;// 获取该URL的端口号
public String getPath( ) 获取该URL的文件路径
public String getFile( ) 获取该URL的文件名
public String getRef( ) 获取该URL在文件中的相对位置
public String getQuery( ) 获取该URL的查询名
@Testpublic void test03() throws Exception {
// 通过一个表示URL地址的字符串可以构造一个URL对象URL url = new URL("http://192.168.15.55/atguigu/hello.txt");
// InputStream in = url.openStream(); //openStream():能从网络上读取数据,获取指定站点的资源URLConnection connection = url.openConnection(); //不仅可以获取指定站点资源,还可以发送资源到指定站点InputStream in = connection.getInputStream();byte[] b = new byte[1024];int len = 0;while((len = in.read(b)) != -1){System.out.println(new String(b, 0, len));}in.close();}
HttpClient
HttpClient HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。
HttpClient基本上是java所有网络请求发起的底层的框架,比如说微服务之间的远程调用、阿里云oss、发送短信。。。
1、执行HTTP方法//1、创建对象HttpClient httpClient = new DefaultHttpClient();//2.创建请求配置:请求方式+地址+参数配置HttpGet httpGet = new HttpGet("http://www.baidu.com");//3.发送请求HttpResponse response = httpClient.execute(httpGet);//4.解析结果System.out.println(response.getStatusLine().getStatusCode());String jsonString = EntityUtils.toString(response.getEntity(), "UTF-8");System.out.println(jsonString);
Socket和ServerSocket
通信基本概念
短连接:socket连接,发送数据,接收数据后马上断开
长连接:建立socket连接后,不管是否使用,保持连接
半包:接收方没有接收到一个完整的包,只接收到包的一部分
粘包:发送方发送的多个包数据到接收方接收时粘成一个包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
分包:出现粘包情况下,需要分包处理或一个数据包被分成多次接收。
Socket通信步骤
不考虑本地的进程间通信。问网络中进程之间如何通信?
1.在本地可以通过进程PID来唯一标识一个进程
2.端口标识了应用层中不同的进程(ip地址,协议,端口)唯一标识网络进程
端口号与IP地址的组合得出一个网络套接字。套接字允许应用程序将 I/O 应用于网络中,并与其他应用程序进行通信
- 通信的两端都要有Socket,是两台机器间通信的端点,网络通信其实就是Socket间的通信。
- Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。
- 客户端和服务器现在可以通过对
Socket
对象的写入和读取来进行进行通信。
端口号标识正在计算机上运行的进程, 被规定为一个 16 位的整数 0~65535。
其中,0~1023被预先定义的服务通信占用(如MySql占用端口3306,http占用端口80等)。除非我们需要访问这些特定服务,否则,就应该使用 1024~65535 这些端口中的某一个进行通信,以免发生端口冲突。
通信步骤
建立连接
1、服务器端先初始化Socket(ServerSocket),然后与端口绑定,对端口进行监听(listen),调用accept阻塞,等待客户端连接
2、客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。
数据交互
客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束
java.net.Socket
客户端 要获取一个Socket
对象通过实例化
setSoTimeout public void setSoTimeout(int timeout) throws SocketException
这个用来设置与socket的inputStream相关的read操作阻塞的等待时间,以毫秒为单位。超过设置的时间了,假如还是阻塞状态,会抛出异常java.net.SocketTimeoutException: Read timed out
这里的阻塞不是指read的时间长短,可以理解为没有数据可读,线程一直在这等待
//客户端
public class ClientDemo {public static void main(String[] args) throws Exception {String str = "《我在精神病院斩神》";//指定要连接的 IP地址和端口号Socket s = new Socket("127.0.0.1", 1314);//读取数据时阻塞链路的超时时间s.setSoTimeout(5000);//以毫秒为单位//发送数据给服务端OutputStream os = s.getOutputStream();os.write(str.getBytes());//发送完毕 禁用此套接字的输出流s.shutdownOutput();//接收服务端的反馈InputStream in = s.getInputStream();byte[] b = new byte[1024];int len = 0;while ((len = in.read(b)) != -1) {System.out.println(new String(b, 0, len));}in.close();os.close();s.close();}
}
Socket 相关API
打开连接到 Socket 的输入/出流
获取与Socket相关联的字节输入流,用于从Socket中读数据。
InputStream getInputStream() throws IOException
-------------------
获取与Socket相关联的字节输出流,用于向Socket中写数据。OutputStream getOutputStream() throws IOException
-------------
关闭监听Socket
void close()throws IOException
isBound(); 如果Socket已经与本地一个端口绑定,返回true;否则返回false
isClosed(); //连接是否已关闭,若关闭,返回true;否则返回false
isConnected;//曾经是否连接成功过。
要判断当前的Socket对象是否处于连接状态
必须同时使用isClose和isConnected方法, 即只有当isClosed返回false,isConnected返回true的时候Socket对象才处于连接状态。
java.net.ServerSocket
- ServerSocket(int port) throws IOException
- ServerSocket(int port, int backlog) throws IOException
- ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException
参数port指定服务器要绑定的端口(服务器要监听的端口),参数backlog指定客户连接请求队列的长度,参数bindAddr指定服务器要绑定的IP地址。
Socket accept() throws IOException 等待客户端的连接请求,返回与该客户端进行通信用的Socket对象
服务器获得一个
Socket
对象则通过accept()
方法的返回值ServerSocket的accept()方法从连接请求队列中取出一个客户的连接请求,然后创建与客户连接的Socket对象,并将它返回。如果队列中没有连接请求,accept()方法就会一直等待,直到接收到了连接请求才返回。
1.服务器中有一个accept()方法创建与客户连接的 Socket 对象[socket],而在没有客户机连接的时候,此方法accept会一直阻塞,所以将其放在一个线程类[ServerListener ]中运行较为合适
服务器从该[socket] 对象中获得输入流和输出流, 就能与客户交换数据
public class ServerListener extends Thread {private int port = 8888;private ServerSocket serverSocket;public static ArrayList<ServerThread> serverThreads = new ArrayList<>();static boolean stop = false;public ServerListener() throws IOException {serverSocket = new ServerSocket(port);System.out.println("服务器启动,端口号为:" + port);}@Overridepublic void run() {//每一个客户机对象都有一个线程来处理while (true) {if (stop) {//关闭资源,跳出循环break;} else {try {//该accept()方法将一直等待,直到客户端连接到服务器上给定的端口。Socket socket = serverSocket.accept();if (!stop) {//正常处理System.out.println("有一个客户机上线了");ServerThread st = new ServerThread(socket);serverThreads.add(st);st.start();} else {this.serverSocket.close();break;}} catch (IOException e) {e.printStackTrace();}}}}//关闭serverSocket的方法public static void closeClient() {stop = true;try {//与本serverSocket建立链接,建立之后立即关闭。这样会打破了accept方法阻塞状态new Socket("127.0.0.1", 8888).close();} catch (IOException e) {e.printStackTrace();}}
}
2.服务器每连接上一个客户端的时候我们都去开启一个线程[ServerThread ],在新开的线程去接收输入输出流,处理输入输出。
socket通信俩端都是socket,不同的是
客户端自己new socket(),new的时候指定ip和端口号来确定去找哪一个socket跟它通信。
服务端,是早早开启socketServer使用accept()监听端口,来一个客户端socket再去创建一个服务端socket去通信,此时俩个socket就都建立起来了
可笑我以前还一直以为ServerSocket就是服务端创建的socket呢,,,一直误会
public class ServerThread extends Thread {private Socket serverScoket;private OutputStream ops;private InputStream ips;boolean isAck = false;boolean isOver = false;public ServerThread(Socket serverScoket) {this.serverScoket = serverScoket;try {ops = serverScoket.getOutputStream();ips = serverScoket.getInputStream();} catch (IOException e) {e.printStackTrace();}}//读取从客户机发来的消息public void readMessage() {try {byte[] bytes = new byte[1024];//循环读取客户端数据到bytes数组while (true) {int len = 0;while ((len = ips.read(bytes)) != -1) {String str = new String(bytes, 0, len);System.out.println("服务器接收客户机消息成功——>" + str);//客户机确认无误,开始通信if (str.equals("client-ack")) {isAck = true;}//客户端发起关闭连接请求if (str.equals("client-over")) {isOver = true;break;//跳出内循环}}if (isOver) {serverScoket.close();//关闭socketServerListener.closeserverScoket();//关闭serverSocketbreak;}}} catch (IOException e) {System.out.println("服务器读取消息失败");e.printStackTrace();}}//给客户机发送消息public void sendMessage(String msa) {if (!isAck) {//未连接客户端,不允许通信return;}try {ops.write(msa.getBytes("GBK"));ops.flush();System.out.println("服务器发送消息成功:" + msa);} catch (IOException e) {e.printStackTrace();System.out.println("服务器发送消息失败");}}//消息随时会有,用线程来执行更为合适public void run() {System.out.println("线程信息 id=" + Thread.currentThread().getId() + "名字=" + Thread.currentThread().getName());try {//给客户端发送确认信息ops.write("server-ack".getBytes("GBK"));ops.flush();} catch (IOException e) {e.printStackTrace();}readMessage();}
}
单独启动客户机
=========================
启动服务器--用telnet命令当客户机
红色方块一直亮着。等待客户机连接,并且主线程没有被accept阻塞住
ServerSocket属性和方法
SO_TIMEOUT表示ServerSocket的accept()方法等待客户连接的超时时间,以毫秒为单位。 如果SO_TIMEOUT的值为0,表示永远不会超时,这是SO_TIMEOUT的默认值。
设置该选项:public void setSoTimeout(int timeout) throws SocketException
读取该选项:public int getSoTimeout () throws IOException
写入网络数据时,调用flush()
方法。
如果不调用flush()
,我们很可能会发现,客户端和服务器都收不到数据,这并不是Java标准库的设计问题,而是我们以流的形式写入数据的时候,并不是一写入就立刻发送到网络,而是先写入内存缓冲区,直到缓冲区满了以后,才会一次性真正发送到网络,这样设计的目的是为了提高传输效率。如果缓冲区的数据很少,而我们又想强制把这些数据发送到网络,就必须调用flush()
强制把缓冲区数据发送出去。
22-05-05 西安 javaSE(18) 网络编程、TCP\IP、Socket通信相关推荐
- java socket ip_JAVA 网络编程 TCP/IP、Socket 和协议设计
[JAVA 网络编程 TCP/IP.Socket 和协议设计] TCP/IP 协议简介 IP 首先我们看 IP(Internet Protocol)协议.IP 协议提供了主机和主机间的通信. 为了完成 ...
- QT入门第七天 网络编程TCP/IP/UDP+Http和JSON解析+qt事件软键盘【CSDN最详细】
网络编程+Http和JSON解析+qt事件软键盘 第一章 QT中的网络编程 [1]涉及到的类 [2]tcp协议的流程 [2.1]服务器的流程 socket-->bind-->listen- ...
- WinSock API网络编程——TCP/IP协议详解
WinSock API网络编程--TCP/IP协议(http://www.impcas.ac.cn/usr/lujun/browse.asp?id=winsock_tcp) ...
- 网络编程-TCP/IP协议栈-TCP协议
TCP协议 TCP协议作用 TCP协议位于协议栈的传输层.当应用层向TCP层发送用于网间传输的,用8字节表示的数据流,TCP则吧数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受到改计算机连 ...
- 网络编程-TCP/IP协议栈-IP协议
协议 协议就是约定的一种规则,例如扑克游戏中约定好的各种规则,2<3<4<5<-等,以此作为游戏规则.当所有人都遵循这个规则,那么久可以不需要任何多余的交流就可以进行游戏,这个 ...
- Socket网络编程(TCP/IP/端口/类)和实例
原文:C# Socket网络编程精华篇 转自:微冷的雨 我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念: TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Ap ...
- C#中开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨
我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念 1.TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基 ...
- python web开发 网络编程 TCP/IP UDP协议
文章目录 1. TCP/IP协议 1.1 IP协议 1.2 TCP协议 2. UDP协议 3. Socket 4. TCP编程 4.1 创建TCP服务器 4.2 创建TCP客户端 4.3 简易聊天工具 ...
- 编写tcp服务器发送hex格式_Android网络编程-TCP/IP协议
在Android网络编程-计算机网络基础一文中得知,IP协议属于网络层,TCP.UDP协议属于传输层. IP协议是TCP/IP协议族的动力,它为上层协议提供无状态.无连接.不可靠的服务. TCP协议是 ...
- 网络编程--TCP/IP协议(一)
目录 前言 一丶网络基础 <1>认识IP地址 1>具体格式 2>组成 3>分类 4>子网掩码 <2>认识MAC地址 二丶网络设备及相关技术 <1& ...
最新文章
- yolov3网络结构笔记
- 一项震动制药行业的研究:大型制药公司AI的生产力
- Pyhon 图片透明化
- dubbo多网卡时,服务提供者的错误IP注册到注册中心导致消费端连接不上
- 【ORACLE 高可用】 作业 :配置ORACLE GoldenGate 1
- python自动化发送邮件_Python发送邮件自动化脚本
- python中异常处理的两种方式_Python 之异常处理
- Greenplum 数据库一体机硬件配置正式开源
- java 数组溢出异常,Java数组超出范围时如何处理多个异常?
- 个人对回调函数的理解(personal understanding of callback function)
- 大疆新品:机甲大师RoboMaster S1介绍(AI 学习小伙伴)
- 这些题你hold住吗?
- android矢量地图画法_Android 百度地图,手绘图形
- Java总结IO篇之字符流
- Maven下载及安装教程详解
- 【数论】基础数论概念
- ASCII码的大小写转换
- spring boot +mybatis plus +html 最佳实践项目
- java htmlparser 使用教程_htmlParser使用教程
- dtm文件生成等高线 lisp_采用人机对话方式从地形图上获取DTM数据的等高线—横断面法...
热门文章
- 留守儿童工作计划安全工作总结范文
- 细谈微信域名防封检测的技术原理及实现方式
- linux系统unzip无法解压超大文件,大于4GB文件
- Windows Terminal美化
- java 的优先级高于||的优先级,而不是同级。
- Spark一路火花带闪电——Spark底层原理介绍
- python实现手势识别
- python画k线图 自定周期_【量化小讲堂- Python、pandas技巧系列】极简方法将日线数据转为周线、月线或其他周期...
- TYD深度学习入门 第一章
- 个人信息管理系统c语言作业,个人物品信息管理系统 C语言.doc