Java网络编程(一)Socket套接字
一、基础知识
1.TCP:传输控制协议。
2.UDP:用户数据报协议。
二、IP地址封装
1.InetAddress类的常用方法
getLocalHost() 返回本地主机的InetAddress对象 InetAddress类型
getByName(String host) 获取指定主机名称的IP地址 InetAddress类型
getHostName() 获取此主机名 String
getHostAddress() 获取主机IP地址 String
isReachable(int timeout) 在timeout指定的毫秒时间内,测试IP地址是否可达 Boolean
2.示例1:测试IP地址从“192.168.131.1”到“192.168.131.150”范围内所有可以访问的主机的名称,如果对方没有安装防火墙,并且网络连接正常的话,都可以访问的。从输出可以看出,192.168.131.1是本地主机的IP,其他地址都不能联通,可能是因为1000毫秒太短或者对方主机装有防火墙的原因。
package bigjunoba.bjtu.iptoname; import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException; public class IPToName {
public static void main(String[] args) {
String IP = null;
for (int i = 1; i <= 150; i++) {
IP = "192.168.131." + i; //生成IP字符串
try {
InetAddress host;
host = InetAddress.getByName(IP); //获取IP封装对象
if (host.isReachable(1000)) { //用1秒的时间测试IP地址是否可达
String hostName = host.getHostName();
System.out.println("IP地址" + IP + "的主机名称是:" + hostName);
}
} catch (UnknownHostException e) { //捕获未知主机异常
e.printStackTrace();
} catch (IOException e) { //捕获输入输出异常
e.printStackTrace();
}
}
System.out.println("搜索完毕!");
}
}
IP地址192.168.131.1的主机名称是:BigjunOba
搜索完毕!
三、套接字
套接字(Socket)是代表计算机之间网络连接的对象,用于建立计算机之间的TCP连接,使计算机之间可以建立连接并实现网络通信。
1.服务器端套接字
服务器端套接字是SercerSocket类的实例对象,用于实现服务器缓存。ServerSocket类将监视指定的端口,并建立客户端到服务器端套接字的连接,也就是客户负责呼叫任务。
(1)创建服务器端套接字
创建服务器端套接字可以使用4种构造方法。
①ServerScoket()
默认构造方法,可以创建未绑定端口号的服务器套接字。服务器套接字的所有构造方法都需要处理IOException异常。
一般格式为:
try {
ServerSocket server = new ServerSocket();
} catch (IOException e) {
e.printStackTrace();
}
②ServerScoket(int port)
该构造方法将创建绑定到port参数指定端口的服务器套接字对象,默认的最大连接队列长度为50,也就是说哦如果连接数量超过50个,将不会再接收新的连接请求。
一般格式为:
try {
ServerSocket server = new ServerSocket(9527);
} catch (IOException e) {
e.printStackTrace();
}
}
③ServerScoket(int port, int backlog)
使用port参数指定的端口号和backlog参数指定的最大连接长度创建服务器端套接字对象,这个构造方法可以指定超出50的连接数量,如300。
一般格式为:
try {
ServerSocket server = new ServerSocket(9527, 300);
} catch (IOException e) {
e.printStackTrace();
}
}
④public ServerSocket(int port, int backlog, InerAddress bindAddr)
使用port参数指定的端口号和backlog参数指定的最大连接队列长度创建服务器端套接字对象。如果服务器有多个IP地址,可以使用bindAddr参数指定创建服务器套接字的地址;如果服务器只有一个IP地址,那么没有必要使用该构造方法。
try {
InetAddress address = InetAddress.getByName("192.168.1.128");
ServerSocket server = new ServerSocket(9527, 300, address);
} catch (IOException e) {
e.printStackTrace();
}
}
(2)接收客户端套接字连接
当服务器建立ServerSocket套接字对象以后,就可以使用该对象的accept()方法接收客户端请求的套接字连接。
语法格式为:
serverSocket.accept();
该方法被调用之后,将等待客户端的连接请求,在接收客户端的套接字连接请求以后,该方法将返回Socket对象,这个Socket对象是已经和客户端建立好连接的套接字,通过这个Socket对象获取客户端的输入输出流来实现数据发送与接收。
该方法可能会产生IOException异常,所以在调用accept()方法时必须捕获并处理该异常。
一般形式为:
try {
server,accept();
} catch (IOException e) {
e.printStackTrace();
}
}
accept()方法将阻塞当前线程,直到接收到客户端的连接请求为止,该方法之后的任何语句都不会执行,必须有客户端发送连接请求;accpet()方法返回Socket套接字以后,当前线程才会继续运行,accpet()方法之后的代码才会被执行。
示例1:System.out.println("已经建立连接!");在server对象接收到客户端的连接请求之前永远都不会执行,这样会导致程序的main主线程阻塞。
package bigjunoba.bjtu.serverSocketTest; import java.io.IOException;
import java.net.ServerSocket; public class ServerSocketTest {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(9527);
serverSocket.accept();
System.out.println("已经建立连接!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
示例2:将上述语句放在一个新的线程中,作为main主线程的子线程,在新的线程中完成等待客户端连接请求并获取客户端Socket对象的任务,这样就不会阻塞main主线程。
package bigjunoba.bjtu.serverSocketTest; import java.io.IOException;
import java.net.ServerSocket; public class ServerSocketTest {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(9527);
serverSocket.accept();
System.out.println("已经建立连接!");
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
2.客户端套接字
Socket类是实现客户端套接字的基础。它采用TCP建立计算机之间的连接,并包含了Java语言所有对TCP有关的操作方法,如建立连接、传输数据、断开连接等。
(1)创建客户端套接字
Socket类定义了多个构造方法,它们可以根据InetAddress对象或者字符串指定的IP地址和端口号创建示例。
①Socket(InetAddress address, int port);
使用address参数传递的IP封装对象和port参数指定的端口号创建套接字实例对象。Socket类的构造方法可能会产生UnknownHostException和IOException异常,在使用该构造方法创建Socket对象时必须捕获和处理这两个异常。
一般形式为:
try {
InetAddress address = InetAddress.getByName("BigjunOba");
int port = 33;
Socket socket = new Socket(address, port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
②Socket(String host, int port);
使用host参数指定的IP地址字符串和port参数指定的整数类型端口号创建套接字实例对象。
一般形式为:
try {
int port = 33;
Socket socket = new Socket("192.168.131.1", port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
③Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
创建一个套接字并将其连接到指定远程地址上的指定远程端口。
一般格式为:
try {
InetAddress localHost = InetAddress.getLocalHost();
InetAddress address = InetAddress.getByName("192.168.131.1");
int port1 = 33;
int port2 = 44;
Socket socket = new Socket(address, port1, localHost, port2) ;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
④Socket(String host, int port, InetAddress localAddr, int localPort)
创建一个套接字并将其连接到指定远程主机上的指定端口。
一般形式为:
try {
InetAddress localHost = InetAddress.getLocalHost();
int port1 = 33;
int port2 = 44;
Socket socket = new Socket("192.168.131.1", port1, localHost, port2) ;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
示例1:检测本地计算机中被使用的端口,端口的检测范围是1~256
package bigjunoba.bjtu.clientSocketTest; import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException; public class CheckPort {
public static void main(String[] args) {
for (int i = 1; i <= 256; i++) {
try {
InetAddress localHost = InetAddress.getLocalHost();
Socket socket = new Socket(localHost, i);
//如果不产生异常,输出该端口被使用
System.out.println("本机已经使用了端口:" + i);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
// e.printStackTrace();
}
}
System.out.println("执行完毕!");
}
本机已经使用了端口:135
执行完毕!
(2)发送和接收数据
Socket对象创建成功以后,代表和对方的主机已经建立了连接,可以接受与发送数据了。Socket提供了两个方法分别获取套接字的输入流和输出流,可以将要发送的数据写入输出流,实现发送功能,或者从输入流读取对方发送的数据,实现接受功能。
①接受数据
Socket对象从数据输入流中获取数据,该输入流包含对方发送的数据,这些数据可能是文件、图片、音频或视频。所以,在实现接受数据之前,必须使用getInputStream()方法获取输入流。
语法格式为:
socket.getInputStream()
②发送数据
Socket对象使用输出流,向对方发送数据,所以,在实现数据发送以前,必须使用getOutputStream()方法获取套接字的输出流。
语法格式为:
socket.getOutputStream()
3.创建一些Socket套接字小程序。
示例1:创建服务器Server程序和客户端Client程序,并实现简单的Socket通信程序。
创建Server服务器类:
package bigjunoba.bjtu.CSTest; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket; public class Server {
public static void main(String[] args) {
try {
//创建服务器套接字
ServerSocket server = new ServerSocket(9527);
System.out.println("服务器启动完毕!");
//等待客户端连接,返回的是已经连接到服务器的客户端socket对象
Socket socket = server.accept();
System.out.println("客户端已经连接上服务器啦!");
//获取客户端socket对象的输入流
InputStream inputStream = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
while (true) {
String string = bufferedReader.readLine();
//如果接收到exit就退出服务器
if (string.equals("exit")) {
break;
}
//如果接收到的不是exit,就输出接收到的内容
System.out.println("接受内容为:" + string);
}
System.out.println("连接断开!");
bufferedReader.close();
reader.close();
inputStream.close();
socket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
创建client客户端类:
package bigjunoba.bjtu.CSTest; import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException; public class Client {
public static void main(String[] args) {
try {
//创建连接服务器的Socket
Socket socket = new Socket("localhost", 9527);
//获取Socket输出
OutputStream outputStream = socket.getOutputStream();
//向服务器发送数据(将字符串转化成字节数组)
outputStream.write("这是客户端发送给服务器的文字\n".getBytes());
//发送退出信息
outputStream.write("exit\n".getBytes());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
先启动服务器:
服务器启动完毕!
再启动客户端:
服务器启动完毕!
客户端已经连接上服务器啦!
接受内容为:这是客户端发送给服务器的文字
连接断开!
示例2:示例1中的程序在运行完一次后,程序就会自动结束,因为Socket socket = server.accept();会阻塞当前的main线程,而且客户端连接一次后,程序执行完之后就直接退出了,这样的效果很不好。为了实现客户端能够实时多次发送数据的功能,考虑将Socket socket = server.accept();这行代码更换到一个更适当的位置,并考虑使用多线程技术来实现多次发送的功能,使得程序更加完善。
(1)首先需要解释一下DataInputStream与InputStream的区别:
DataInputStream类继承了InputStream类,比普通的InputStream多了一些方法,DataInputStream、DataOutputStream并没有改变InputStream或OutputStream的行为,读入或写出时的动作还是InputStream、OutputStream负责。DataInputStream、DataOutputStream只是在实现对应的方法时,动态地为它们加上类型判断功能。readUTF()的作用,是从输入流中读取UTF-8编码的数据,并以String字符串的形式返回。writeUTF(value:String)的作用是 :将String字符串转换成UTF-8编码的字节流并写入输出流。
(2)内部类:如果内部类和main方法在同一个类中,那么因为静态方法不能调用动态方法,所以可以将内部类定义成静态static,然后在创建类时就已经new出了实例,因此不需要new语句,调用的时候直接调用即可。
(3)明确服务器端和客户端的发送和接收
客户端:从输入流中接收数据,使用输出流发送数据。即dataOutputStream.writeUTF(line);是客户端发送给服务器的数据,dataInputStream.readUTF()是客户端接收服务器发来的数据。
服务器端:从输入流中接收数据,使用输出流发送数据。即dataOutputStream.writeUTF(replyMessage);是服务器发送给客户端的数据,dataInputStream.readUTF()服务器接收客户端发来的数据。
(3)server服务器端程序修改为:
package bigjunoba.bjtu.CSTest2; import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; public class Server {
public static void main(String[] args) {
try {
//创建服务器套接字
@SuppressWarnings("resource")
ServerSocket server = new ServerSocket(8023);
System.out.println("服务器启动完毕!");
while (true) {
//等待客户端连接,只有当一个客户端连接上才会返回已经连接到服务器的客户端socket对象
Socket socket = server.accept();
System.out.println("客户端已经连接上服务器啦!");
//客户端连接上服务器后,就开启通信线程
new CommunicationThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
} public static class CommunicationThread extends Thread{
Socket socket;
DataInputStream dataInputStream;
DataOutputStream dataOutputStream; public CommunicationThread(Socket socket) {
this.socket = socket;
try {
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
} public void run() {
super.run();
String message = null;
try {
//接收从客户端发来的数据
while ((message = dataInputStream.readUTF()) != null) {
System.out.println("客户端发来的信息是:" + message);
String replyMessage = "OK!我已经收到了:" + message;
//发送回应数据给客户端
dataOutputStream.writeUTF(replyMessage);
System.out.println("服务器发送给客户端的回应:" + replyMessage);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
(4)client客户端程序修改为:
package bigjunoba.bjtu.CSTest2; import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner; public class Client {
public static void main(String[] args) {
try {
@SuppressWarnings("resource")
//连接到服务器
Socket socket = new Socket("localhost", 8023);
System.out.println("客户端启动完毕!");
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
String line = null;
listenServerReply(dataInputStream);
//读取从键盘输入的第一行
while ((line = scanner.nextLine()) != null) {
//发送数据给服务器端
dataOutputStream.writeUTF(line);
System.out.println("客户端发送给服务器的信息是:" + line);
}
} catch (Exception e) {
e.printStackTrace();
}
} //监听服务器端发送回来的信息
public static void listenServerReply(final DataInputStream dataInputStream) {
new Thread() {
public void run() {
super.run();
String line = null;
try {
//接收从服务器端发送回来的回应信息
while ((line = dataInputStream.readUTF()) != null) {
System.out.println("客户端从服务器接收到的回应是:" + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
(5)首先启动服务器端,服务器端打印程序为:
服务器启动完毕!
(6)然后启动客户端,
客户端输出为:
客户端启动完毕!
服务器端输出为:
服务器启动完毕!
客户端已经连接上服务器啦!
(7)在客户端控制台出打印一些信息
客户端输出为:
客户端启动完毕!
Hello,你好啊!
客户端发送给服务器的信息是:Hello,你好啊!
客户端从服务器接收到的回应是:OK!我已经收到了:Hello,你好啊!
服务器端输出为:
服务器启动完毕!
客户端已经连接上服务器啦!
客户端发来的信息是:Hello,你好啊!
服务器发送给客户端的回应:OK!我已经收到了:Hello,你好啊!
四、数据报
Java语言可以使用TCP和UDP两种通信协议实现网络通信,其中TCP通信由Socket套接字实现,而UDP通信需要使用DatagramSocket类实现。
和TCP通信不同,UDP传递信息的速度更快,但是没有TCP的高可靠性,当用户通过UDP发送信息之后,无法确定能否正确地传送到目的地。虽然UDP是一种不可靠的通信协议,但是大多数场合并不需要严格的、高可靠性的通信,它们需要的是快速的信息发送,并能容忍一些小的错误,那么使用UDP通信来实现会更合适一些。
UDP将数据打包,也就是通信中所传递的数据包,然后将数据包发送到指定目的地,对方会接收数据包,然后查看数据包中的数据。
1.DatagramPacket
该类是UDP锁传递的数据包,即打包后的数据。数据包用来实现无连接包投递的服务,每个数据包仅根据包中包含的信息从一台计算机传送到另一台计算机,传送的多个包可以选择不同的路由,也可能按不同的顺序到达。
(1)DatagramPacket(byte[] buf, int length)
该构造方法用来创建数据包实例,这个数据包实例将接收长度为length的数据包。
语法格式为:
DatagramPacket(byte[] buf, int length)
(2)DatagramPacket(byte[] buf, int length, InetAddress address, int port)
创建数据包实例,用来将长度为length的数据包发送到address参数指定地址和port参数指定端口号的主机。length参数必须小于等于buf数组的长度。
语法格式为:
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
2.DatagramSocket
该类是用于发送和接收数据的数据包套接字。数据包套接字是数据包传送服务的发送或接收点。要实现UDP通信的数据就必须创建数据包套接字。
常用的构造方法有3个:
(1)DatagramSocket()
默认的构造方法,该构造方法将使用本机任何可用的端口创建数据包套接字实例。在创建DatagramSocket类的实例时,有可能会产生SocketException异常,所以,在创建数据包套接字时,应该捕获并处理该异常。
一般格式为:
try {
DatagramSocket datagramSocket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
(2)DatagramSocket(int port)
创建数据包套接字并将其绑定到port参数指定的本机端口,端口号取值必须在0~65535.
一般格式为:
try {
DatagramSocket datagramSocket = new DatagramSocket(8023);
} catch (SocketException e) {
e.printStackTrace();
}
(3)DatagramSocket(int port, InetAddress Iaddr)
绑定数据包套接字,将其绑定到Iaddr参数指定的本机地址和port参数指定的本机端口号。本机端口号取值必须在0~65535之间。
一般格式为:
try {
InetAddress localHost = InetAddress.getLocalHost();
DatagramSocket datagramSocket = new DatagramSocket(8023, localHost);
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}
3.数据报通信程序
示例:使用两个雷实现UDP通信程序设计。
创建服务器端程序:
package bigjunoba.bjtu.UDPTest; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException; public class Server {
public static void main(String[] args) {
byte[] buf = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
try {
@SuppressWarnings("resource")
DatagramSocket datagramSocket = new DatagramSocket(8023);
System.out.println("服务器启动完毕!");
datagramSocket.receive(datagramPacket);
int length = datagramPacket.getLength();
String message = new String(datagramPacket.getData(), 0, length);
String ip = datagramPacket.getAddress().getHostAddress();
System.out.println("从" + ip + "发送来了信息:" + message);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
创建客户端程序:
package bigjunoba.bjtu.UDPTest; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException; public class Client {
public static void main(String[] args) {
try {
InetAddress address = InetAddress.getByName("127.0.0.1");
@SuppressWarnings("resource")
DatagramSocket datagramSocket = new DatagramSocket();
System.out.println("客户端启动完毕!");
byte[] data = "hello,我是客户端,我来访问服务器了!".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(data, data.length, address, 8023);
datagramSocket.send(datagramPacket);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
先启动服务器程序,然后再启动客户端程序,服务器控制台的输出为:
服务器启动完毕!
从127.0.0.1发送来了信息:hello,我是客户端,我来访问服务器了!
五、网络聊天程序开发
使用Swing设置程序UI界面,并结合Java语言多线程技术使网络聊天程序更加符合实际需求,即可以不间断地收发多条信息。
(1)创建ClientFrame类,该类包含多个成员变量。
Java网络编程(一)Socket套接字的更多相关文章
- 网络编程与socket套接字
网络编程与socket套接字 传输层 PORT协议 port是一种接口,数据通过它在计算机和其他设备(比如打印机,鼠标,键盘或监视器)之间,网络之间和其他直接连接的计算机之间传递 TCP协议 传输 ...
- linux网络编程-(socket套接字编程UDP传输)
今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...
- 31_网络编程(Socket套接字编程)_讲义
今日内容介绍 1.网络三要素及传输协议 2.实现UDP协议的发送端和接收端 3.实现TCP协议的客户端和服务器 4.TCP上传文件案例 01网络模型 *A:网络模型 TCP/IP协议中的四层分别是应用 ...
- 【网络编程】Socket套接字网络编程模型
一.Linux网络模型 -- Socket套接字编程 图片:Socket 抽象层 Socket编程--不同协议,统一接口 Socket的实质就是一个接口, 利用该接口,用户在使用不同的网络协议时,操作 ...
- 02网络编程( socket套接字+TCP粘包 )
目录 02 网络编程 一.socket套接字编程 二.简易代码模板 2.1 服务端 2.2 客户端 三.通信循环及代码优化 四.黏包现象 五.struct模块 六.简易版本报头 七.上传文件数据 * ...
- python网络编程:socket套接字
一.socket 二.TCP服务器 三.TCP客户端 四.UDP服务器 五.UDP客户端 六.聊天的客户端 七.聊天的服务器 一.socket """ 学习网络编程 其实 ...
- Unix网络编程--卷一:套接字联网API
UNIX网络编程--卷一:套接字联网API 本书面对的读者是那些希望自己编写的程序能够使用成为套接字(socket)的API进行彼此通信的人. 目录: 0.准备环境 1.简介 2.传输层:TCP.UD ...
- VC++学习之网络编程中的套接字
VC++学习之网络编程中的套接字 套接字,简单的说就是通信双方的一种约定,用套接字中的相关函数来完成通信过程.应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问 ...
- [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]
[网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...
- Linux网络编程:原始套接字简介
Linux网络编程:原始套接字编程 一.原始套接字用途 通常情况下程序员接所接触到的套接字(Socket)为两类: 流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的T ...
随机推荐
- thymeleaf 遍历使用案例
1.语法: th:each属性用于迭代循环,语法:th:each="obj,iterStat:${objList}" 迭代对象可以是List,Map,数组等; 2.说明:iterS ...
- Android开发——Toolbar常用设置
本篇笔记用来记录常用的Toolbar设置,如Toolbar颜色设置,显示返回按钮,显示右边三个点按钮 之前Android 使用的ActionBar,Android5.0开始,谷歌官方推荐使用Toolb ...
- 序列标注(HMM/CRF)
目录 简介 隐马尔可夫模型(HMM) 条件随机场(CRF) 马尔可夫随机场 条件随机场 条件随机场的特征函数 CRF与HMM的对比 维特比算法(Viterbi) 简介 序列标注(Sequence Ta ...
- 新手安装vue-cli脚手架
首先这片文章借鉴了很多博主的,再此对他们表示感谢. 什么是vue? Vue.js是一套构建用户界面的渐进式框架.Vue 只关注视图层,采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 A ...
- Flutter 的基本控件
文本控件 Text 支持两种类型的文本展示,一个是默认的展示单一样式文本 Text,另一个是支持多种混合样式的富文本 Text.rich. 单一样式文本 Text 单一样式文本 Text 的初始化,是 ...
- 04-02 AdaBoost算法
目录 AdaBoost算法 一.AdaBoost算法学习目标 二.AdaBoost算法详解 2.1 Boosting算法回顾 2.2 AdaBoost算法 2.3 AdaBoost算法目标函数优化 三 ...
- HashMap底层数据结构详解
一.HashMap底层数据结构 JDK1.7及之前:数组+链表 JDK1.8:数组+链表+红黑树 关于HashMap基本的大家都知道,但是为什么数组的长度必须是2的指数次幂,为什么HashMap的加载 ...
- Springboot2.x + ShardingSphere 实现分库分表
之前一篇文章中我们讲了基于Mysql8的读写分离(文末有链接),这次来说说分库分表的实现过程. 概念解析 垂直分片 按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用. 在拆分之前 ...
- c语言中double类型数据的输入和输出
double a;scanf("%f",&a); //应用scanf("%lf",&a);执行上面语句时,发现double类型的输入不能使用 ...
- pdfminer API介绍:pdf网页爬虫
安装 pip install pdfminer 爬取数据是数据分析项目的第一个阶段,有的加密成pdf格式的文件,下载后需要解析,使用pdfminer工具. 先介绍一下什么是pdfminer 下面是官方 ...