【网络~】
网络
- 一级目录
- 二、socket套接字
- 三、UDP数据报套接字
- 四、TCP流套接字
一级目录
1.局域网、广域网
2.IP地址是什么?
IP地址是标识主机在网络上的地址
IP地址是如何组成的?
点分十进制,将32位分为四个部分,每个部分一个字节,范围是0-255
3.端口号是什么?
端口号是区分一台主机上不同的应用程序。
4.客户端和服务器
客户端是发起请求方。服务器是响应请求。
1.一对一形式:客户端发送一个请求,服务器响应一个请求;
2.一对多形式:客户端发送一个请求,服务器响应多个请求;
3.多对一形式:客户端发送多个请求,服务器响应一个请求;
4.多对多形式:客户端发送多个请求,服务器响应多个请求。
5.协议
主机和主机之间通信需要遵循一些协议。
两台主机之间通信,需要通过一个 五元组 来描述通信
五元组是什么?
源ip,源端口,目的ip,目的端口,协议类型。
6.协议分段
1.OSI模型:物理层->数据链路层->网络层->运输层->会话层->表示层->应用层
2.TCP/IP五层模型:物理层->数据链路层->网络层->运输层->应用层
应用层:应用程序
运输层:只关注起点和终点
网络层:关注网络中任意两台机器的网络通信路径和具体的传输方式
数据链路层:相邻主机之间的数据传输
物理层:网络传输的基础设施
下层协议给上层协议提供功能支持,上层协议依赖下层协议。
7.网络编程
网络编程是什么?
在网络上,不同进程通过编码方式进行数据通信,叫做网络编程。
二、socket套接字
1.socket套接字是什么?
socket套接字是操作系统提供的网络通信技术,是基于TCP/IP协议的操作基本单元。基于socket应用程序开发就是网络编程。
2.socket套接字的分类
1.数据报套接字:基于UDP协议
2.流套接字:基于TCP协议
UDP和TCP的区别:
UDP:1.无连接;2.不可靠传输;3.面向数据报;4.全双工。
TCP:1.有连接;2.可靠传输;3.面向字节流;4.全双工。
什么是可靠传输?
发送方知道接受方是否正确收到信息。
不可靠传输:发送发不知道接受方是否正确收到信息。
三、UDP数据报套接字
1.Java数据报套接字通信模型(基于UDP协议)
DatagramSocket:描述一个soket对象,在操作系统中,一切皆文件,管理硬件设备和软件资源,都是通过文件的方式来管理,网卡是硬件设备,要想操作网卡,需要写一个socket文件,通过读写socket文件来操作网卡。
socket实际上是一个文件描述符表。
DatagramPacket:描述一个UDP数据报。
2.利用DatagramSocket和DatagramPacket来写一个回显服务器(UDP socket)
//客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;public class UdpEchoClient02 {DatagramSocket socket=null;String serverIp;int serverPort;public UdpEchoClient02(String serverIp,int serverPort) throws SocketException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new DatagramSocket();}//客户端需要知道服务器的ip地址和端口号public void start() throws IOException {Scanner in=new Scanner(System.in);while (true){System.out.println("client02:用户输入请求->");String request=in.next();if(request.equals("exist")){System.out.println("系统退出");return;}DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);socket.send(requestPacket);DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());String log=String.format("[%s,%s],request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public static void main(String[] args) throws IOException {UdpEchoClient02 udpEchoClient02=new UdpEchoClient02("127.0.0.1",7010);udpEchoClient02.start();}
}
//服务器端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;//服务器端
public class UdpEchoService02 {DatagramSocket socket=null;public UdpEchoService02(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {System.out.println("service02:启动服务器");while(true){DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);String request=new String(requestPacket.getData(),0,requestPacket.getLength());String response=getResponse(request);DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);String log=String.format("[%s,%d]:request:%s;response:%s",requestPacket.getAddress(),requestPacket.getPort(),request,response);System.out.println(log);}}public String getResponse(String request){return request;}public static void main(String[] args) throws IOException {UdpEchoService02 udpEchoService02=new UdpEchoService02(7010);udpEchoService02.start();}
}
结果:
3."翻译"程序
英译汉:客户端输入请求为英文单词,返回的响应式中文解释。
//客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;//客户端
public class UdpClient {DatagramSocket socket=null;String serverIp;int serverPort;public UdpClient(String serverIp,int serverPort) throws SocketException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new DatagramSocket();}public void start() throws IOException {Scanner in=new Scanner(System.in);while(true){//1.用户输入请求String request=in.next();if(request.equals("exit")){System.out.println("系统退出");return;}//2.根据用户输入构造请求,并将请求发送给服务器DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);socket.send(requestPacket);//3.接收服务器的响应DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//4.解析服务器响应String response=new String(responsePacket.getData(),0,responsePacket.getLength());//5.日志打印String log=String.format("[%s,%d],request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public static void main(String[] args) throws IOException {UdpClient udpClient=new UdpClient("127.0.0.1",9090);udpClient.start();}
}
//服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.HashMap;//服务器端
public class UdpServer {DatagramSocket socket=null;HashMap<String,String> hashMap=new HashMap<>();public UdpServer(int port) throws SocketException {socket=new DatagramSocket(port);//初始化hashMaphashMap.put("你好","hello");hashMap.put("明天","tomorrow");hashMap.put("客户端","client");hashMap.put("服务器","server");}public void start() throws IOException {System.out.println("启动服务器");while(true){//1.接收用户请求DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//2.解析用户请求String request=new String(requestPacket.getData(),0,requestPacket.getLength());//3.根据用户请求构造响应String response=process(request);DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);//4.打印日志String log=String.format("[%s,%d]:request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public String process(String request){return hashMap.getOrDefault(request,"该词在词典中不存在");}public static void main(String[] args) throws IOException {UdpServer udpServer=new UdpServer(9090);udpServer.start();}
}
客户端:
服务器:
4.扩展"翻译器"
上面代码用的是HashMap,在下面的代码中,让代码连接数据库,待查词中文,去数据库中查表,查出对应的英文。
a.数据库设计
//1.数据库设计
//db.sql
create database if not exists test_2_8 ;
use test_2_8;drop table if exists translate;
create table translate (id int primary key auto_increment,chinese varchar(50),english varchar(50)
);
insert into translate values(null,"你好","hello");
insert into translate values(null,"服务器","server");
insert into translate values(null,"客户端","client");
b.针对数据表,创建数据表对象
//创建数据表对象
//+----+-----------+---------+
// | id | chinese | english |
// +----+-----------+---------+
// | 1 | 你好 | hello |
// | 2 | 服务器 | server |
// | 3 | 客户端 | client |
// +----+-----------+---------+
public class Translate {private int id;private String chinses;private String english;@Overridepublic String toString() {return "Translate{" +"id=" + id +", chinses='" + chinses + '\'' +", english='" + english + '\'' +'}';}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getChinses() {return chinses;}public void setChinses(String chinses) {this.chinses = chinses;}public String getEnglish() {return english;}public void setEnglish(String english) {this.english = english;}
}
c.连接数据库
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class Util {private static final String URL="jdbc:mysql://127.0.0.1:3306/test_2_8?characterEncoding=utf8&&useSSL=false";private static final String USERNAME="root";private static final String PASSWORD="root";static DataSource dataSource=new MysqlDataSource();public static Connection getConnection() throws SQLException {((MysqlDataSource)dataSource).setUrl(URL);((MysqlDataSource)dataSource).setUser(USERNAME);((MysqlDataSource)dataSource).setPassword(PASSWORD);return dataSource.getConnection();}public static void getClose(Connection connection, PreparedStatement statement, ResultSet resultSet){if(resultSet!=null){try {resultSet.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(statement!=null){try {statement.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(connection!=null){try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}
}
d.客户端代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;public class UdpClient {String serverIp;int serverPort;DatagramSocket socket=null;public UdpClient(String serverIp,int serverPort) throws SocketException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new DatagramSocket();}public void start() throws IOException {Scanner scanner=new Scanner(System.in);while(true){System.out.println("->");//1.用户输入请求,并且构造请求String request=scanner.next();if(request.equals("exit")){System.out.println("程序退出");return;}DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);//2.将请求发送服务器socket.send(requestPacket);//3.从服务器接收响应DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());//4.打印日志String log=String.format("[%s,%d]:request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public static void main(String[] args) throws IOException {UdpClient udpClient=new UdpClient("127.0.0.1",9090);udpClient.start();}
}
e.服务器代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;//服务器
public class UdpServer {DatagramSocket socket=null;public UdpServer(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while(true){//1.接收请求DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//2.解析请求String request=new String(requestPacket.getData(),0,requestPacket.getLength());//3.构造响应String response=process(request);DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());//4.给客户端发送响应socket.send(responsePacket);//打印日志String log=String.format("[%s,%d]:request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public String process(String request){Connection connection=null;PreparedStatement preparedStatement=null;ResultSet resultSet=null;Translate translate=new Translate();try{connection=Util.getConnection();String sql="select * from translate where chinese=?";preparedStatement=connection.prepareStatement(sql);preparedStatement.setString(1,request);resultSet=preparedStatement.executeQuery();if(resultSet.next()){translate.setEnglish(resultSet.getString("english"));}else{String t=new String("词典中不存在该词");return t;}}catch(SQLException e){e.printStackTrace();}finally {Util.getClose(connection,preparedStatement,resultSet);}return translate.getEnglish();}public static void main(String[] args) throws IOException {UdpServer server=new UdpServer(9090);server.start();}
}
结果展示:
数据库:
客户端:
服务器:
四、TCP流套接字
1.ServerSocket
2.Socket
2.写一个回显服务器
a.客户端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;//客户端
public class TcpEchoClient02 {Socket socket=null;String serverIp;int serverPort;public TcpEchoClient02(String serverIp,int serverPort) throws IOException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new Socket(serverIp,serverPort);}public void start(){Scanner in=new Scanner(System.in);System.out.println("客户端");try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){System.out.println("->");String request=in.next();//将用户需求发送给服务器PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(request);printWriter.flush();//接收服务器发送的响应Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){break;}String response=scanner.next();//打印日志String log=String.format("[%s,%d]:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) throws IOException {TcpEchoClient02 tcpEchoClient02=new TcpEchoClient02("127.0.0.1",9090);tcpEchoClient02.start();}
}
b.服务器
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;//服务器
public class TcpEchoServer02 {ServerSocket listenSocket=null;public TcpEchoServer02(int port) throws IOException {listenSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while (true){Socket socket=listenSocket.accept();processConnection(socket);}}public void processConnection(Socket socket){String log2=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log2+"服务器连接成功");try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){String log=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log+"客户端下线");break;}String request=scanner.next();String response=process(request);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();//打印日志String log=String.format("[%s,%d]:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpEchoServer02 tcpEchoServer02=new TcpEchoServer02(9090);tcpEchoServer02.start();}
}
结果展示:
客户端:
服务器:
上面的代码存在一个问题:
在同一时间只能支持一个客户端去访问一个服务器。
如果想要代码实现在同一时间内多个客户端访问一个服务器,该如何实现呢?
引入 多进程
只需要修改服务器代码模块
多线程下的服务器代码
idea编译器端默认一个类只能启动一次,多个客户端需要多次启动客户端代码,所以,需要更改编译器的设置:
多线程—服务器端的代码:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;//多线程回显服务器
public class TcpThreadEchoServer {ServerSocket listenSocket=null;public TcpThreadEchoServer(int port) throws IOException {listenSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while(true){Socket clientSocket=listenSocket.accept();Thread t=new Thread(){@Overridepublic void run(){processConnection(clientSocket);}};t.start();}}public void processConnection(Socket clientSocket){String log=String.format("[%s,%d]",clientSocket.getInetAddress(),clientSocket.getPort());System.out.println(log+"客户端上线");try(InputStream inputStream=clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream()){while(true){Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){log=String.format("[%s,%d]",clientSocket.getInetAddress(),clientSocket.getPort());System.out.println(log+"下线");break;}String request=scanner.next();String response=process(request);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();log=String.format("[%s,%d]:request:%s,response:%s",clientSocket.getInetAddress(),clientSocket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpThreadEchoServer tcpThreadEchoServer=new TcpThreadEchoServer(9090);tcpThreadEchoServer.start();}
}
上面代码涉及到线程的创建和销毁,频繁的创建和销毁线程,开销会比较大,所以,引入了线程池.
服务器端的代码需要进行改变
线程池—服务器端的代码
//线程池---回显服务器
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;//线程池--回显服务器
public class TcpThreadPoolServer {ServerSocket listenSocket=null;public TcpThreadPoolServer(int port) throws IOException {listenSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while (true) {Socket socket=listenSocket.accept();//--------------------线程池---------------------------ExecutorService executorService= Executors.newCachedThreadPool();executorService.submit(new Runnable(){@Overridepublic void run(){processConnection(socket);}});}}public void processConnection(Socket socket){String log=String.format("【%s,%d】:客户端上线了",socket.getInetAddress(),socket.getPort());System.out.println(log);try(InputStream inputStream=socket.getInputStream();OutputStream outputstream=socket.getOutputStream()){while(true){Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){log=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log+"客户下线");break;}String request=scanner.next();String response=process(request);PrintWriter printWriter=new PrintWriter(outputstream);printWriter.println(response);printWriter.flush();log=String.format("[%s,%d]:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpThreadPoolServer tcpThreadPoolServer=new TcpThreadPoolServer(9090);tcpThreadPoolServer.start();}
}
结果:客户端1:
客户端2:
服务器:
场景:在某些时刻,服务器会收到很多个请求,服务器收到多个请求,需要创建多个线程,当请求过多的时候,服务器资源(eg:CPU,内存资源)不够用,服务器最后会崩溃。该如何解决在某些时刻,服务器收到多个请求这种场景呢?
1.引入协程。协程比线程更轻量;
2.IO多路复用;
3.引入多个服务器。
3.利用tcp流套接字写一个"翻译器"–“汉译英”—连接数据库
数据库和数据表的创建,和上面基于UDP的套接字实现方法是一样的。
只是客户端和服务器端的socket不一样。
a.客户端代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;//翻译器--客户端
public class TcpClient {Socket socket=null;String serverIp;int port;public TcpClient(String serverIp,int port) throws IOException {this.serverIp=serverIp;this.port=port;socket=new Socket(serverIp,port);}public void start(){Scanner in=new Scanner(System.in);try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){System.out.println("->");String request=in.next();if(request.equals("exit")){break;}PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(request);printWriter.flush();Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){break;}String response=scanner.next();String log=String.format("【%s,%d】:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpClient tcpClient=new TcpClient("127.0.0.1",9090);tcpClient.start();}
}
b.服务器端代码
import test0209.util.DBUtil;
import test0209.util.Translate;import javax.xml.transform.Result;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;//翻译器--服务器
public class TcpServer {ServerSocket listenSocket=null;public TcpServer(int port) throws IOException {listenSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while(true){Socket socket=listenSocket.accept();ExecutorService executorService= Executors.newCachedThreadPool();executorService.submit(new Runnable() {@Overridepublic void run() {processConnection(socket);}});}}public void processConnection(Socket socket){String log=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log+"客户端上线");try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){log=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log+"客户端下线");break;}String request=scanner.next();String response=process(request);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();log=String.format("[%s,%d]:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}}//翻译器public String process(String request){Connection connection=null;PreparedStatement preparedStatement=null;ResultSet resultSet=null;try {connection=DBUtil.getConnection();String sql="select * from translate where chinese=?";preparedStatement=connection.prepareStatement(sql);preparedStatement.setString(1,request);resultSet=preparedStatement.executeQuery();if(!resultSet.next()){String log=new String("词典中不存在该词语");return log;}Translate translate=new Translate();translate.setEnglish(resultSet.getString("english"));return translate.getEnglish();} catch (SQLException throwables) {throwables.printStackTrace();}return new String("没有查到");}public static void main(String[] args) throws IOException {TcpServer tcpServer=new TcpServer(9090);tcpServer.start();}
}
结果截图:
客户端1:
客户端2:
服务器:
相关文章:
【网络~】
网络一级目录二、socket套接字三、UDP数据报套接字四、TCP流套接字一级目录 1.局域网、广域网 2.IP地址是什么? IP地址是标识主机在网络上的地址 IP地址是如何组成的? 点分十进制,将32位分为四个部分,每个部分一个字节ÿ…...
手写JavaScript中的call、bind、apply方法
手写JavaScript中的call、bind、apply方法 call方法 call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。 function Product(name, price) {this.name name;this.price price; }function Food(name, price) {Product.call(this, name, price);t…...
JAVA练习46-将有序数组转换为二叉搜索树
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 提示:这里可以添加本文要记录的大概内容: 2月10日练习内容 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目-…...
linux(centos7.6)docker
官方文档:https://docs.docker.com/engine/install/centos/1安装之前删除旧版本的docker2安装yum install-y yum-utils3配置yum源 不用官网的外国下载太慢 推荐阿里云yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.r…...
微信小程序滚动穿透问题
文章目录1、catchtouchmove"true"2、page-meta3、wx.setPageStyle做小程序的开发业务中,经常会使用弹窗,当弹窗里的内容过多时,要滚动查看,然后经常会遇到滚动弹窗,弹窗底下页面也跟着滚。解决思路ÿ…...
安全—06day
负载均衡反向代理下的webshell上传负载均衡负载均衡下webshell上传的四大难点难点一:需要在每一台节点的相同位置上传相同内容的webshell难点二:无法预测下一次请求是哪一台机器去执行难点三:当我们需要上传一些工具时,麻烦来了&a…...
PostgreSQL入门
PostgreSQL入门 简介 PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES, 版本 4.2为基础的对象关系型数据库管理系统(ORDBMS) 支持大部分SQL标准并且提供了许多现代特性 复杂查询外键触发器可更新视图事务完整性多版本并发控制 …...
自媒体人都在用的免费音效素材网站
视频剪辑、自媒体人必备的剪辑音效素材网站,免费下载,建议收藏! 1、菜鸟图库 音效素材下载_mp3音效大全 - 菜鸟图库 菜鸟图库是一个综合性素材网站,站内涵盖设计、图片、办公、视频、音效等素材。其中音效素材就有上千首…...
Java数据结构中二叉树的深度解析及常见OJ题
本篇文章讲述Java数据结构中关于二叉树相关知识及常见的二叉树OJ题做法讲解(包含非递归遍历二叉树) 目录 一、二叉树 1.1二叉树概念 1.2特殊的二叉树 1.3二叉树性质 1.4二叉树基本性质定理题 1.5二叉树遍历基本操作 1.6二叉树遍历的前中后非递归写法 1.7…...
算法顶级比赛汇总
可参赛的算法比赛 阿里云天池大数据竞赛 时间:每年各个季度很多类型都会出题(比赛总时间大概为两个月) 内容:各个类型的算法题都会出、奖金上万不等 形式:在线提交(提交后在线检查结果)、离线…...
Android MVI框架搭建与使用
MVI框架搭建与使用前言正文一、创建项目① 配置AndroidManifest.xml② 配置app的build.gradle二、网络请求① 生成数据类② 接口类③ 网络请求工具类三、意图与状态① 创建意图② 创建状态四、ViewModel① 创建存储库② 创建ViewModel③ 创建ViewModel工厂五、UI① 列表适配器②…...
第九节 使用设备树实现RGB 灯驱动
通过上一小节的学习,我们已经能够编写简单的设备树节点,并且使用常用的of 函数从设备树中获取我们想要的节点资源。这一小节我们带领大家使用设备树编写一个简单的RGB 灯驱动程序,加深对设备树的理解。 实验说明 本节实验使用到STM32MP1 开…...
Ubuntu 系统下Docker安装与使用
Ubuntu 系统下Docker安装与使用Docker安装与使用Docker安装安装环境准备工作系统要求卸载旧版本Ubuntu 14.04 可选内核模块Ubuntu 16.04 使用 APT 安装安装 Docker CE使用脚本自动安装启动 Docker CE建立 docker 用户组测试 Docker 是否安装正确镜像加速Docker使用拉取镜像创建…...
DHCP安全及防范
DHCP安全及防范DHCP面临的威胁DHCP饿死攻击仿冒DHCP Server攻击DHCP中间人攻击DHCP Snooping技术的出现DHCP Snooping防饿死攻击DHCP Snooping防止仿冒DHCP Server攻击DHCP Snooping防止中间人攻击DHCP Snooping防止仿冒DHCP报文攻击DHCP面临的威胁 网络攻击无处不在ÿ…...
【流畅的python】第一章 Python数据模型
文章目录第一章 Python 数据模型1.1 python风格的纸牌1.2 如何使用特殊方法-通过创建一个向量类的例子1.3 特殊方法汇总第一章 Python 数据模型 python最好的品质是一致性 python解释器碰到特殊句法时,会使用特殊方法去激活一些基本的对象操作 这些特殊的方法以两个…...
from文件突然全部变为类cs右击无法显示设计界面
右击也不显示查看设计器 工程文件 .csproj中将 <Compile Include"OperatorWindows\Connection.cs" /> <Compile Include"OperatorWindows\Connection.Designer.cs"> <DependentUpon>Connection.cs</DependentUpon> &…...
使用arthas中vmtool命令查看spring容器中对象的某个属性
场景: 线上环境我想查看spring中容器某个对象的属性值 vmtool命令 方式一: vmtool --action getInstances -c [类加载器的hash] --className [目标类全路径] --limit 10 -x 2 实例:查询该类的全部属性情况(该类是一个spri…...
四种幂等性解决方案
什么是幂等性? 幂等是一个数学与计算机学概念,在数学中某一元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同。 在计算机中编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。 幂等…...
【Nacos】Nacos配置中心客户端配置更新源码分析
上文我们说了服务启动的时候从远程Nacos服务端拉取配置,这节我们来说下Nacos服务端配置的变动怎么实时通知到客户端,首先需要注册监听器。 注册监听器 NacosContextRefresher类会监听应用启动发布的ApplicationReadyEvent事件,然后进行配置…...
按钮防抖与节流-vue2
防抖与节流,应用场景有很多,例如:禁止重复提交数据的场景、搜索框输入搜索条件,待输入停止后再开始搜索。 防抖 点击button按钮,设置定时器,在规定的时间内再次点击会重置定时器重新计时,在规定…...
Cadence IC617虚拟机导入后,Calibre DRC报License错误的保姆级修复指南
Cadence IC617虚拟机导入后Calibre DRC报License错误的终极解决方案 当你兴冲冲地打开从同事那里拷贝的Cadence IC617虚拟机镜像,准备开始芯片设计工作时,突然跳出的Calibre DRC license错误提示就像一盆冷水浇下来。这种"拿来即用"的环境本应…...
Stl.Fusion实际应用案例:从HelloCart到复杂业务系统的演进
Stl.Fusion实际应用案例:从HelloCart到复杂业务系统的演进 【免费下载链接】Stl.Fusion Build real-time apps (Blazor included) with less than 1% of extra code responsible for real-time updates. Host 10-1000x faster APIs relying on transparent and near…...
Day3:拆箱ROS2|一起搭建机器人开发车间
Day1:一起学习了ros2是什么以及ros2为机器人开发提供了哪些核心功能. Day2一起安装了ros2。 接下来自然会想到如果现在要用ROS2开发一个机器人,应该怎样开始? 下面我们以雷达小车机器人举例说明: 1、需要为机器人创建一个【工作空间】作为顶层…...
自动化测试(十二) 分布式系统测试-缓存-注册中心与链路追踪验证
分布式系统测试:缓存、注册中心与链路追踪验证上篇咱们搞定了消息队列测试,今天继续深入分布式系统的其他组件——Redis缓存、服务注册中心、分布式链路追踪。这些"基础设施"的测试往往被忽略,但出了问题定位起来最头疼。一、Redis…...
企业级AI应用如何通过Taotoken统一管理多个大模型API调用
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 企业级AI应用如何通过Taotoken统一管理多个大模型API调用 在构建企业级AI应用时,技术团队常常面临一个现实挑战&#x…...
2026AI大模型API聚合系统排行榜:四大主流中转API及特色玩家谁能脱颖而出?
随着AI技术大规模落地,AI大模型API聚合系统成为企业快速接入前沿智能能力、降低技术门槛的关键工具。目前市场上的服务商众多,企业在选择时往往会考虑稳定性、合规性、接入成本等因素。为了帮助企业解决这一难题,本文对当下主流的四大AI大模型…...
对比直接使用官方 API,Taotoken 在批量处理任务中的用量可视化优势
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比直接使用官方 API,Taotoken 在批量处理任务中的用量可视化优势 当开发团队或个人开发者需要处理大量文本生成任务时…...
SITS 2026图计算方案深度解析,独家披露金融风控与生物医药两大场景的GNN工程化适配矩阵(含12个可复用配置模板)
更多请点击: https://intelliparadigm.com 第一章:AI原生图计算应用:SITS 2026图神经网络工程化方案 SITS 2026 是面向大规模动态图场景的AI原生图计算框架,深度融合GNN训练、图拓扑实时更新与边缘-云协同推理能力。其核心设计摒…...
先进制程重塑晶圆代工格局:从HPC需求到供应链博弈
1. 行业现状:先进制程如何重塑晶圆代工格局最近和几位在芯片设计公司负责流片的朋友聊天,大家讨论最激烈的,除了产能紧张,就是到底要不要、以及何时上更先进的工艺节点。一个普遍的共识是:7纳米和5纳米这类所谓“先进制…...
2026年项目管理工具测评:10款主流软件对比与企业选型建议
本文测评 ONES、Tower、Jira、Asana、monday、ClickUp、Notion、Trello、Microsoft Project、Smartsheet 十款项目管理工具,帮助选型人员从组织规模、项目复杂度、协作方式与治理需求出发,判断哪类项目管理工具更适合自身团队。一、10款项目管理工具速览…...
















