java网络相关
@@ -115,3 +115,8 @@ git push <remote> --tags
|
||||
```
|
||||
|
||||
将本地所有标签推送到远程仓库中
|
||||
|
||||
### 使用远程分支覆盖本地分支
|
||||
git fetch --all
|
||||
git reset --hard origin/dev (这里dev要修改为对应的分支名,将本地分支只想远程分支的地提交)
|
||||
git pull origin dev
|
||||
0
Java三方库/apa
Normal file
1
Java三方库/apache-httpcomponents.md
Normal file
@@ -0,0 +1 @@
|
||||
https://hc.apache.org/
|
||||
30
Java三方库/commons-bean.md
Normal file
@@ -0,0 +1,30 @@
|
||||
https://commons.apache.org/
|
||||
引入依赖
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.9.4</version>
|
||||
</dependency>
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
BeanUtils/BeanUtilsBean
|
||||
拷贝: cloneBean/copyProperties/copyProperty
|
||||
获取:getArrayProperty/getSimpleProperty/getProperty
|
||||
其他操作:setProperty设置属性 populate将Bean设置到Map中 describe将Bean转成Map
|
||||
1
|
||||
2
|
||||
3
|
||||
PropertyUtils类
|
||||
判断:isReadable/isWriteable
|
||||
获取:
|
||||
getProperty/getSimpleProperty/getPropertyType
|
||||
getReadMethod/getWriteMethod/getIndexedProperty/setIndexedProperty
|
||||
getMappedProperty/setMappedProperty/getNestedProperty/setNestedProperty
|
||||
getPropertyDescriptor/getPropertyEditorClass
|
||||
拷贝和设置:copyProperties/setProperty/setSimpleProperty /clearDescriptors
|
||||
————————————————
|
||||
版权声明:本文为CSDN博主「white camel」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
||||
原文链接:https://blog.csdn.net/m0_37989980/article/details/126396868
|
||||
63
Java三方库/commons-collections4.md
Normal file
@@ -0,0 +1,63 @@
|
||||
https://commons.apache.org/
|
||||
## 引入依赖
|
||||
```xml
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.4</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## CollectionUtils 集合工具类
|
||||
```
|
||||
添加/删除:addAll/addIgnoreNull/retainAll/removeAll/
|
||||
获取:
|
||||
find/get/containsAny/index/size/sizeIsEmpty/select/selectRejected/subtract
|
||||
typedCollection
|
||||
判断:
|
||||
isEmpty/isNotEmpty/isFull/exists/isEqualCollection/
|
||||
isSubCollection/isProperSubCollection
|
||||
转换:
|
||||
collect/transform/transformedCollection/predicatedCollection
|
||||
unmodifiableCollection/synchronizedCollection
|
||||
计算:cardinality/countMatches/maxSize
|
||||
过滤:filter
|
||||
集合:intersection/union/disjunction 交集,并集,差集
|
||||
其他操作:
|
||||
reverseArray 翻转 forAllDo 给每个元素执行闭包
|
||||
getCardinalityMap 转成Map,key是元素,value是次数
|
||||
```
|
||||
|
||||
## ListUtils-List工具类
|
||||
```
|
||||
判断: isEqualList
|
||||
集合:intersection/sum/union/retainAll 交集,并集,合集,差集
|
||||
操作:removeAll/hashCodeForList
|
||||
子集: typedList/subtract/fixedSizeList
|
||||
转换处理:synchronizedList/unmodifiableList/predicatedList/transformedList/lazyList
|
||||
```
|
||||
|
||||
## SetUtils-Set集合工具类
|
||||
```
|
||||
判断:isEqualSet
|
||||
转换处理:
|
||||
transformedSet/transformedSortedSet/predicatedSet/predicatedSortedSet
|
||||
unmodifiableSet/synchronizedSet/synchronizedSortedSet
|
||||
orderedSet/typedSet/typedSortedSet
|
||||
操作:hashCodeForSet
|
||||
```
|
||||
|
||||
## MapUtils-Map工具类
|
||||
```
|
||||
获取:getObject/getString/getXXX/getXXXValue 获取指定类型值,getXXXValue 如果没有值则默认值
|
||||
子集:fixedSizeMap/fixedSizeSortedMap/typedMap/typedSortedMap
|
||||
判断:isEmpty/isNotEmpty
|
||||
转换:
|
||||
predicatedMap/predicatedSortedMap/transformedMap/transformedSortedMap/
|
||||
synchronizedMap/synchronizedSortedMap/
|
||||
unmodifiableMap/unmodifiableSortedMap/multiValueMap/orderedMap
|
||||
toMap/toProperties/lazyMap/lazySortedMap
|
||||
添加移除:safeAddToMap/putAll
|
||||
其他操作:invertMap/debugPrint/verbosePrint
|
||||
```
|
||||
56
Java三方库/commons-io.md
Normal file
@@ -0,0 +1,56 @@
|
||||
https://commons.apache.org/
|
||||
## 引入依赖
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
```
|
||||
## FileUtils 文件操作工具类
|
||||
```
|
||||
文件夹操作:
|
||||
copyDirectory/deleteDirectory/cleanDirectory/getTempDirectory/getTempDirectoryPath
|
||||
moveDirectory/moveDirectoryToDirectory/moveFileToDirectory/moveToDirectory
|
||||
forceMkdir/getUserDirectory/getUserDirectoryPath
|
||||
文件操作:
|
||||
touch/copyFile/copyURLToFile/moveFile/deleteQuietly/forceDelete/forceDeleteOnExit
|
||||
toFile/toFiles/toURLs
|
||||
isFileNewer/isFileOlder
|
||||
readLines/readFileToByteArray/readFileToString/lineIterator/openOutputStream
|
||||
write/writeLines/writeByteArrayToFile/writeStringToFile/openInputStream
|
||||
其他操作:
|
||||
iterateFiles/listFiles/contentEquals/sizeOf/sizeOfDirectory
|
||||
```
|
||||
## IOUtils 流操作工具类
|
||||
```
|
||||
读操作:lineIterator/read/readLines
|
||||
写操作:write/writeLines
|
||||
转换: toInputStream/toBufferedInputStream/toByteArray/toCharArray/toString
|
||||
其他操作:copy/copyLarge/contentEquals/skip/skipFully/closeQuietly
|
||||
```
|
||||
## FilenameUtils 文件名工具类
|
||||
```
|
||||
获取:
|
||||
getName/getBaseName/getPrefix/getPrefixLength/getExtension
|
||||
getPath/getFullPath/getFullPathNoEndSeparator/getPathNoEndSeparator
|
||||
判断:
|
||||
isExtension/equals/equalsNormalized/equalsOnSystem
|
||||
其他操作:
|
||||
removeExtension/indexOfExtension
|
||||
separatorsToSystem/separatorsToUnix/separatorsToWindows
|
||||
indexOfLastSeparator
|
||||
```
|
||||
## 其他工具类
|
||||
```
|
||||
文件比较器:
|
||||
CompositeFileComparator/DefaultFileComparator/DirectoryFileComparator
|
||||
ExtensionFileComparator/LastModifiedFileComparator/NameFileComparator
|
||||
PathFileComparator/PathFileComparator
|
||||
文件过滤器:
|
||||
AgeFileFilter/AndFileFilter/CanReadFileFilter/CanWriteFileFilter
|
||||
DelegateFileFilter/DirectoryFileFilter/EmptyFileFilter/FalseFileFilter/FileFileFilter
|
||||
FileFilterUtils/HiddenFileFilter/MagicNumberFileFilter/NameFileFilter/NotFileFilter
|
||||
OrFileFilter/PrefixFileFilter/RegexFileFilter/SizeFileFilter/SuffixFileFilter
|
||||
TrueFileFilter/WildcardFileFilter/WildcardFilter
|
||||
```
|
||||
152
Java三方库/commons-lang3.md
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
## 引入依赖
|
||||
```
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
```
|
||||
## 数据类型工具类
|
||||
### StringUtils 字符串工具类
|
||||
```java
|
||||
包含判断方法:contains/containsXXX
|
||||
字符串替换方法:replace/replaceXXX
|
||||
获取子串:substring/substringXXX
|
||||
判断方法:
|
||||
1、isEmpty/isNotEmpty/isBlank/isNotBlank/isNumeric/isWhitespace
|
||||
2、sartsWith/startsWithAny/endsWith/endsWithIgnoreCase
|
||||
索引(index):indexOf/indexOfXXX/tIndexOf/lastIndexOfXXX
|
||||
处理方法:
|
||||
abbreviate 缩短 capitalise 首字母 repeat 重复 left/right/center 左右中间
|
||||
removeXXX 移除 trimXXX 去空 reverseXXX 翻转 stripXXX 移除
|
||||
defaultXXX 默认 lowerCase/upperCase deleteXXX 删除处理
|
||||
splitXXX分解处理 join 拼接
|
||||
```
|
||||
|
||||
### StringEscapeUtils 转义字符串工具类
|
||||
StringEscapeUtils类可以对html js xml sql 等代码进行转义来防止SQL注入
|
||||
```
|
||||
escapeCsv/unescapeCsv/escapeHtml/unescapeHtml/escapeJava/unescapeJava
|
||||
escapeJavaScript/unescapeJavaScript/escapeXml/unescapeXml/escapeSql
|
||||
```
|
||||
|
||||
### NumberUtils 数字工具类
|
||||
|
||||
```
|
||||
创建数字:createXXX 创建Integer,Float,Double,Number,BigDecimal,BigInteger等数字
|
||||
字符转数字:toXXX 字符串转数字:Byte,Double,Float,Int,Long,Short
|
||||
判断是否数字:isDigits/isNumber
|
||||
其他方法:compare,max,min,
|
||||
```
|
||||
|
||||
### ArrayUtils 数组工具类
|
||||
|
||||
```
|
||||
添加移除:add,addAll,remove,removeElement,
|
||||
拷贝:clone
|
||||
判断:contains,isEmpty,isNotEmpty,isEquals,isSameLength,
|
||||
其他:getLength,indexOf,lastIndexOf,nullToEmpty,reverse,subArray,
|
||||
转换:toMap,toObject,toPrimitive,toString
|
||||
```
|
||||
### EnumUtils 枚举工具类
|
||||
```
|
||||
getEnum/getEnumIgnoreCase/getEnumList/getEnumMap
|
||||
iterator
|
||||
```
|
||||
## 随机数工具类
|
||||
### RandomUtils 随机数工具类
|
||||
```
|
||||
nextBoolean/nextInt/nextLong/nextFloat/nextDouble
|
||||
```
|
||||
|
||||
### RandomStringUtils 随机字符串工具类
|
||||
```
|
||||
random/randomNumeric/randomAlphabetic/randomAscii
|
||||
```
|
||||
## 日期时间工具类
|
||||
### DateUtils 日期工具类
|
||||
```
|
||||
说明:XXX表示milisecends,seconds,minutes,hours,days,weeks,months,years
|
||||
时间加减:add/addXXX
|
||||
时间设置:setXXX
|
||||
获取片段:getFragmentInXXX 获取date的1月1日0点0分0秒到指定时间的片段值
|
||||
判断: isSameDay/isSameInstant/isSameLocalTime
|
||||
转换: parseDate/parseDateStrictly
|
||||
取模: ceiling/round/truncate
|
||||
时间段:iterator 注意rangeStyle=1到4表示周范围以及偏移,5和6表示月偏移
|
||||
```
|
||||
|
||||
### DateFormatUtils时间格式化
|
||||
```
|
||||
格式化:format/formatUTC
|
||||
```
|
||||
### DurationFormatUtils时间段格式化
|
||||
```
|
||||
formatDuration/formatDurationHMS/formatDurationISO
|
||||
formatPeriod/formatPeriodISO
|
||||
formatDurationWords
|
||||
```
|
||||
|
||||
### StopWatch 秒表
|
||||
```
|
||||
start/stop/suspend/split/resume/reset/unsplit
|
||||
getSplitTime/getStartTime/getTime/
|
||||
toSplitString/toString
|
||||
```
|
||||
|
||||
|
||||
## 反射工具类
|
||||
|
||||
### ClassUtils 类工具
|
||||
```
|
||||
获取:
|
||||
1、类和接口 :getClass/getAllInterfaces/getAllSuperclasses/getShortClassName
|
||||
2、包:getPackageName/getPackageCanonicalName
|
||||
3、方法:getPublicMethod
|
||||
转换:
|
||||
1、toClass/convertClassesToClassNames/convertClassNamesToClasses/
|
||||
2、primitivesToWrappers/primitiveToWrapper/wrappersToPrimitives/wrapperToPrimitive
|
||||
判断:isAssignable/isInnerClass
|
||||
```
|
||||
|
||||
### MethodUtils
|
||||
```
|
||||
getAccessibleMethod/getMatchingAccessibleMethod
|
||||
invokeMethod/invokeStaticMethod/invokeExactMethod/invokeExactStaticMethod
|
||||
```
|
||||
|
||||
### FieldUtils
|
||||
```
|
||||
getField/readField/writeField
|
||||
getDeclaredField/readDeclaredField/writeDeclaredField
|
||||
readDeclaredStaticField/readStaticField/writeDeclaredStaticField/writeStaticField
|
||||
```
|
||||
|
||||
### ConstructorUtils
|
||||
```
|
||||
getAccessibleConstructor/getMatchingAccessibleConstructor
|
||||
invokeConstructor/invokeExactConstructor
|
||||
```
|
||||
|
||||
## ObjectUtils 对象工具类
|
||||
```
|
||||
max/min/toString/identityToString/appendIdentityToString/defaultIfNull
|
||||
```
|
||||
## SystemUtils 系统属性工具类
|
||||
```
|
||||
getJavaHome/getJavaIoTmpDir/getJavaVersion/getUserDir/getUserHome/
|
||||
isJavaAwtHeadless/isJavaVersionAtLeast
|
||||
```
|
||||
|
||||
## SerializationUtils 序列化工具类
|
||||
```
|
||||
clone/deserialize/serialize
|
||||
```
|
||||
|
||||
## LocaleUtils 本地工具类
|
||||
```
|
||||
availableLocaleList/availableLocaleSet
|
||||
countriesByLanguage
|
||||
localeLookupList/toLocale/isAvailableLocale/languagesByCountry
|
||||
```
|
||||
@@ -10,7 +10,9 @@ Java对象和json格式之间转换。
|
||||
* jsonobject如果没有指定java对象
|
||||
|
||||
|
||||
https://blog.csdn.net/qq_37436172/article/details/127334627
|
||||
|
||||
https://www.jianshu.com/p/f5407d45d590
|
||||
## 序列化
|
||||
|
||||
|
||||
@@ -40,7 +42,7 @@ public abstract class JSON {
|
||||
|
||||
## 反序列化
|
||||
|
||||
```
|
||||
```java
|
||||
package com.alibaba.fastjson;
|
||||
|
||||
public abstract class JSON {
|
||||
@@ -62,4 +64,50 @@ public abstract class JSON {
|
||||
// 将JSON字符串反序列为JSONObject
|
||||
public static JSONObject parseObject(String text);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Map泛型反序列化
|
||||
JSON串转为 Map,含有泛型的 JSON 反序列化
|
||||
|
||||
### JSON串 --> Map<String, Object>
|
||||
```java
|
||||
@Test
|
||||
public void test() {
|
||||
Map<String, Order> orderMap = new HashMap<String, Order>(){{
|
||||
put("001", new Order(1001L, "T001"));
|
||||
put("002", new Order(1002L, "T002"));
|
||||
}};
|
||||
String jsonStr = JSON.toJSONString(orderMap);
|
||||
|
||||
// 没有泛型 是不安全的
|
||||
Map map = JSON.parseObject(jsonStr);
|
||||
|
||||
// TypeReference 但构造方法是protected,所以使用它的子类
|
||||
// 用匿名内部类作为 TypeReference 子类
|
||||
TypeReference<Map<String, Order>> typeReference = new TypeReference<Map<String, Order>>() {};
|
||||
Map<String, Order> result = JSON.parseObject(jsonStr, typeReference);
|
||||
```
|
||||
### JSON串 --> Map<String, List<Object>>
|
||||
|
||||
```java
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
Map<Integer, List<Order>> data = new HashMap<Integer, List<Order>>() {{
|
||||
put(2022001, Arrays.asList(new Order(1001L, "T001")));
|
||||
put(2022002, Arrays.asList(new Order(1002L, "T002")));
|
||||
}};
|
||||
String jsonStr = JSON.toJSONString(data);
|
||||
|
||||
Map<Integer, List<Order>> map = JSON.parseObject(jsonStr, new TypeReference<Map<Integer, List<Order>>>() {});
|
||||
|
||||
// 方式一:使用 Type
|
||||
Type type = new TypeReference<Map<Integer, List<Order>>>(){}.getType();
|
||||
Map<Integer, List<Order>> resultMap = JSON.parseObject(jsonStr, type);
|
||||
|
||||
// 方式二
|
||||
Map<Integer, List<Order>> integerListMap = JSON.parseObject(jsonStr, new TypeReference<Map<Integer, List<Order>>>() {});
|
||||
|
||||
}
|
||||
```
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
### web开发
|
||||
以下三个是Http服务实现。技能够提供http协议的服务端,也能实现http协议的客户端。是有协议的。
|
||||
1. Servlet 最基本的http服务实现方法。采用多线程阻塞的方式。包括服务端和HttpClient,可以独立使用
|
||||
2. Java ws.rs - Resteasy 基于标准接口的http服务的实现方法。包括服务端和ResteasyClient,可以独立使用
|
||||
3. Spring MVC 基于Servlet的http服务的封装和实现方法。包括服务端和RestTemplate,可以独立使用
|
||||
4. Spring Flux 基于Netty的http服务的封装和实现方法。包括服务端和WebClient,可以独立使用
|
||||
1. JDK&Jetty&Netty,提供了不同的socket通信方式,可以自己实现http服务的客户端和服务端
|
||||
2. apache Servlet 最基本的http服务实现方法。采用多线程阻塞的方式。包括服务端和HttpClient,可以独立使用
|
||||
3. Java ws.rs - Resteasy 基于标准接口的http服务的实现方法。包括服务端和ResteasyClient,可以独立使用
|
||||
4. Spring MVC 基于Servlet的http服务的封装和实现方法。包括服务端和RestTemplate,可以独立使用
|
||||
5. Spring Flux 基于Netty的http服务的封装和实现方法。包括服务端和WebClient,可以独立使用
|
||||
64
Java基础教程/Java实用技巧/05 Java远程调试.md
Normal file
@@ -0,0 +1,64 @@
|
||||
## 1 server端
|
||||
|
||||
### 启动命令
|
||||
> 打jar包允许被远程调试
|
||||
```
|
||||
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9091 -jar xxx.jar
|
||||
|
||||
```
|
||||
|
||||
### 参数说明
|
||||
|
||||
1. transport: 指定运行的被调试应用和调试者之间的通信协议,它由几个可选值: dt_socket:主要的方式,采用socket方式连接。 dt_shmem:采用共享内存方式连接,仅支持 Windows 平台。
|
||||
2. server: 指定当前应用作为调试服务端还是客户端,默认为n。 如果你想将当前应用作为被调试应用,设置该值为 y,如果你想将当前应用作为客户端,作为调试的发起者,设置该值为n。
|
||||
3. suspend: 当前应用启动后,是否阻塞应用直到被连接,默认值为 y。 在大部分的应用场景,这个值为 n,即不需要应用阻塞等待连接。一个可能为 y的应用场景是,你的程序在启动时出现了一个故障,为了调试,必须等到调试方连接上来后程序再启动。
|
||||
4. address: 暴露的调试连接端口,默认值为 8000。 此端口一定不能与项目端口重复,且必须是服务器开放的端口。
|
||||
5. onthrow: 当程序抛出设定异常时,中断调试。
|
||||
6. onuncaught: 当程序抛出未捕获异常时,是否中断调试,默认值为 n。
|
||||
7. launch: 当调试中断时,执行的程序。
|
||||
8. timeout: 该参数限定为java -agentlib:jdwp=…可用,单位为毫秒ms。 当 suspend = y 时,该值表示等待连接的超时;当 suspend = n 时,该值表示连接后的使用超时。
|
||||
|
||||
### 参考命令
|
||||
```
|
||||
-agentlib:jdwp=transport=dt_socket,server=y,address=8000:以 Socket 方式监听 8000 端口,程序启动阻塞(suspend 的默认值为 y)直到被连接。
|
||||
-agentlib:jdwp=transport=dt_socket,server=y,address=localhost:8000,timeout=5000:以
|
||||
Socket 方式监听 8000 端口,当程序启动后 5 秒无调试者连接的话终止,程序启动阻塞(suspend 的默认值为
|
||||
y)直到被连接。
|
||||
-agentlib:jdwp=transport=dt_shmem,server=y,suspend=n:选择可用的共享内存连接地址并使用
|
||||
stdout 打印,程序启动不阻塞。
|
||||
-agentlib:jdwp=transport=dt_socket,address=myhost:8000:以 socket 方式连接到 myhost:8000上的调试程序,在连接成功前启动阻塞。
|
||||
agentlib:jdwp=transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub:以
|
||||
Socket 方式监听 8000 端口,程序启动阻塞(suspend 的默认值为 y)直到被连接。当抛出 IOException
|
||||
时中断调试,转而执行 usr/local/bin/debugstub程序。
|
||||
```
|
||||
|
||||
### 直接运行Java程序允许远程调试
|
||||
命令
|
||||
```
|
||||
-Xdebug -Xrunjdwp:transport=dt_socket,address=8088,server=y,suspend=n
|
||||
```
|
||||
具体参数详解:
|
||||
|
||||
1. -Xdebug 通知JVM工作在DEBUG模式下;
|
||||
2. -Xrunjdwp 通知JVM使用(Java debug wire protocol)运行调试环境。该参数同时包含了一系列的调试选项;
|
||||
3. **transport**指定了调试数据的传送方式,dt_socket是指用SOCKET模式,另有dt_shmem指用共享内存方式,其中,dt_shmem只适用于Windows平台;
|
||||
4. address 调试服务器的端口号,客户端用来连接服务器的端口号;
|
||||
5. server=y/n VM 是否需要作为调试服务器执行;
|
||||
6. suspend=y/n 是否在调试客户端建立连接之后启动 VM;
|
||||
|
||||
## IDEA本地
|
||||
|
||||
1. 在 IDEA 中,点击 Edit Configurations,在弹框中点击 + 号,然后选择Remote。
|
||||

|
||||
|
||||
2. 填写服务器的地址及端口,点击 OK 即可。
|
||||

|
||||
|
||||
3. 配置完毕后,DEBUG 调试运行即可。
|
||||

|
||||
|
||||
4. 配置完毕后点击保存即可,因为我配置的 suspend=n,因此服务端程序无需阻塞等待我们的连接。我们点击 IDEA 调试按钮,当我访问某一接口时,能够正常调试。
|
||||

|
||||
|
||||
|
||||
|
||||
BIN
Java基础教程/Java实用技巧/image/2023-03-01-13-43-46.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
Java基础教程/Java实用技巧/image/2023-03-01-13-44-05.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
Java基础教程/Java实用技巧/image/2023-03-01-13-44-25.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
Java基础教程/Java实用技巧/image/2023-03-01-13-45-10.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
195
Java基础教程/Java并发编程/11 Java只执行一次.md
Normal file
@@ -0,0 +1,195 @@
|
||||
|
||||
## 问题说明
|
||||
|
||||
有时我们希望java程序能在高并发操作下,某个函数只执行一次。
|
||||
1. 一般情况下,设置一个门控值,每次执行前检查是否执行过,如果没有执行过,则设置为false,并执行。如果为true则不执行。如果是单线程,该方法能够发挥作用。
|
||||
2. 多线程情况下,如果多个线程同时判断门控值,都得到true,就会同时进入执行结果。
|
||||
|
||||
## 1 高并发下的原子操作
|
||||
|
||||
|
||||
|
||||
使用一个原子Boolean值作为门控值。同一时间进入判断的值只有一个,能保证多线程情况下,该函数仍然只执行一次。
|
||||
```java
|
||||
private AtomicBoolean inited = new AtomicBoolean(false);
|
||||
|
||||
/**
|
||||
* @see ServerManager#getServerList()
|
||||
*/
|
||||
@Override
|
||||
public List<ServerNode> getServerList() {
|
||||
if (inited.compareAndSet(false, true)) {
|
||||
initServerList();
|
||||
}
|
||||
return new ArrayList<ServerNode>(serverNodes);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 2 使用两次判断加锁
|
||||
先判断该值,然后加锁再判断执行。能够保证一下两点内容
|
||||
1. 第二次判断操作的互斥性,即第二次判断在加锁条件下执行,该判断只会在同一时间发生一次。
|
||||
2. 外层的判断能够减少执行完成后,其他的高并发访问不再加锁,提高程序的性能。
|
||||
|
||||
```
|
||||
if(value == true){
|
||||
synchronized(this){
|
||||
if(value == true){
|
||||
initMethod();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
一、介绍
|
||||
AtomicBoolean是通过原子方式更新 boolean 值。AtomicBoolean用于诸如原子更新标志之类的应用程序,但是不能替换boolean类使用。
|
||||
|
||||
二、原理
|
||||
AtomicBoolean 内部持有了一个 volatile变量修饰的value,
|
||||
底层通过对象在内存中的偏移量(valueOffset)对应的旧值与当前值进行比较,
|
||||
相等则更新并返回true;否则返回false。
|
||||
|
||||
即CAS的交换思想.
|
||||
AtomicBoolean 内部可以保证,在高并发情况下,同一时刻只有一个线程对变量修改成功。
|
||||
/**
|
||||
* Atomically update Java variable to <tt>x</tt> if it is currently
|
||||
* holding <tt>expected</tt>.
|
||||
* @return <tt>true</tt> if successful
|
||||
*/
|
||||
public final native boolean compareAndSwapInt(Object o, long offset,
|
||||
int expected,
|
||||
int x);
|
||||
Unsafe.compareAndSwapInt()介绍
|
||||
|
||||
三、应用
|
||||
1、AtomicBoolean 示例
|
||||
public class AtomicBooleanDemo1 {
|
||||
|
||||
// 设置初始化值为false,参数通过cas操作更新为true
|
||||
private static AtomicBoolean initialized = new AtomicBoolean(false);
|
||||
|
||||
public void init() {
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
// 此处只会有一个线程进入
|
||||
System.out.println(Thread.currentThread().getName() + " init success");
|
||||
} else {
|
||||
System.out.println(Thread.currentThread().getName() + " cas 失败");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final AtomicBooleanDemo1 demo1 = new AtomicBooleanDemo1();
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
demo1.init();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
2、 使用volatile 替换
|
||||
|
||||
public class AtomicBooleanDemo2 {
|
||||
|
||||
// 设置初始化值为false,通过volatile变量保证线程可见性
|
||||
private static volatile boolean initialized;
|
||||
|
||||
public void init() {
|
||||
if (initialized == false) {
|
||||
initialized = true;
|
||||
// 此处只会有一个线程进入
|
||||
System.out.println(Thread.currentThread().getName() + " init success");
|
||||
} else {
|
||||
System.out.println(Thread.currentThread().getName() + " cas 失败");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final AtomicBooleanDemo2 demo1 = new AtomicBooleanDemo2();
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
demo1.init();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
针对这种boolean类型的并发操作,可以使用AtomicBoolean进行设置即可
|
||||
|
||||
三、源码分析
|
||||
public class AtomicBoolean implements java.io.Serializable {
|
||||
private static final long serialVersionUID = 4654671469794556979L;
|
||||
// setup to use Unsafe.compareAndSwapInt for updates
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
// 对象在内存中的映射偏移量
|
||||
private static final long valueOffset;
|
||||
|
||||
|
||||
// static静态块,随AtomicBoolean 类加载时执行一次,可见valueOffset针对所有对象在内存中的映射
|
||||
// 值都是同一个
|
||||
static {
|
||||
try {
|
||||
valueOffset = unsafe.objectFieldOffset
|
||||
(AtomicBoolean.class.getDeclaredField("value"));
|
||||
} catch (Exception ex) { throw new Error(ex); }
|
||||
}
|
||||
|
||||
private volatile int value;
|
||||
|
||||
// 构造函数,对value赋默认值
|
||||
public AtomicBoolean(boolean initialValue) {
|
||||
value = initialValue ? 1 : 0;
|
||||
}
|
||||
|
||||
// 无参构造,value默认值为0
|
||||
public AtomicBoolean() {
|
||||
}
|
||||
|
||||
}
|
||||
将expect和AtomicBoolean的value进行比较,若一致则更新为update,否则返回false
|
||||
|
||||
/**
|
||||
* Atomically sets the value to the given updated value
|
||||
* if the current value {@code ==} the expected value.
|
||||
*
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return {@code true} if successful. False return indicates that
|
||||
* the actual value was not equal to the expected value.
|
||||
*/
|
||||
public final boolean compareAndSet(boolean expect, boolean update) {
|
||||
int e = expect ? 1 : 0;
|
||||
int u = update ? 1 : 0;
|
||||
// 通过unsafe的cas方法操作,比较并替换,底层通过lock前缀加锁实现原子性
|
||||
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
|
||||
}
|
||||
|
||||
四、unsafe方法的实现原理
|
||||
1、unsafe的compareAndSet内部是如何保证原子性的?
|
||||
底层通过cmpxchg汇编命令处理,如果是多处理器会使用lock前缀,可以达到内存屏障的效果,来进行隔离。
|
||||
|
||||
具体分析见 【Unsafe中的compareAndSet实现】
|
||||
|
||||
|
||||
|
||||
五、总结
|
||||
AtomicBoolean内存代码无锁,比常规的synchronized或lock锁效率较高
|
||||
既然volatile可以修饰boolean类型,为什么还需要有AtomicBoolean原子类?
|
||||
CAS 都是会存在ABA问题(可采用版本号解决等)
|
||||
|
||||
|
||||
补充:
|
||||
A: boolean类型本身作为标记,保证了原子性,加上volatile保证了可见性,所以此处两种方式都可以,但对于int等其他类型字段volatile则不可保证原子操作,必须依赖于原子类操作等
|
||||
|
||||
AtomicBoolean可以保证原子执行,保证线程安全;
|
||||
volatile 只能保证线程可见性、指令重排序等;保证不了原子性。
|
||||
boolean类型作为标记字段,本身保证了原子性
|
||||
156
Java基础教程/Java标准库/11 Unsafe类.md
Normal file
@@ -0,0 +1,156 @@
|
||||
我们在阅读JAVA并发编程中JUC包下的类源码的时候,经常看见Unsafe类,但是有一个疑惑,为什么处理并发安全的类,要起名为“不安全”呢?后来对于Unsafe深入理解之后,才知道作者的原意,这里说的不安全并不是针对于并发操作,而是指:该类对于普通程序员来说是“危险”的,一般开发者不应该也不会用到此类。因为Unsafe类功能过于强大,提供了一些可以绕开JVM的更底层的功能。它让JAVA拥有了想C语言的指针一样操作内存空间的能力,能够提升效率,但是也带来了指针的复杂性等问题,所以官方并不建议使用,并且没提供文档支持,甚至计划在高版本去除该类。
|
||||
|
||||
|
||||
|
||||
## 1 Unsafe构造及获取
|
||||
|
||||
Unsafe类使用final修饰,不允许继承,且构造函数是private,使用了饿汉式单例,通过一个静态方法getUnsafe()来获取实例。
|
||||
|
||||

|
||||
|
||||
## 2 Unsage功能概述
|
||||

|
||||
|
||||
内存管理
|
||||
|
||||
Unsafe的内存管理功能主要包括:普通读写、volatile读写、有序写入、直接操作内存等分配内存与释放内存的功能。
|
||||
|
||||
3.1.1、普通读写
|
||||
|
||||
Unsafe可以读写一个类的属性,即便这个属性是私有的,也可以对这个属性进行读写。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
getInt等用于从对象的指定偏移地址处读取一个值。putInt等用于在对象指定偏移地址处写入一个值。其他原始类型也提供有对应的方法。
|
||||
|
||||
此外,Unsafe的getByte、putByte方法提供了直接在一个地址上进行读写的功能。
|
||||
|
||||
3.1.2、volatile读写
|
||||
|
||||
普通的读写无法保证可见性和有序性,而volatile读写就可以保证可见性和有序性;但是相对普通读写要更加昂贵。
|
||||
|
||||
|
||||
|
||||
3.1.3、有序写入
|
||||
|
||||
有序写入只保证写入的有序性,不保证可见性,就是说一个线程的写入不保证其他线程立马可见。
|
||||
|
||||
而与volatile写入相比putOrderedXX写入代价相对较低,putOrderedXX写入不保证可见性,但是保证有序性,所谓有序性,就是保证指令不会重排序。
|
||||
|
||||
3.1.4、直接操作内存
|
||||
|
||||
Unsafe提供了直接操作内存的能力:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
也提供了一些获取内存信息的方法:getAddress、addressSize、pageSize
|
||||
|
||||
值得注意的是:利用copyMemory方法可以实现一个通用的对象拷贝方法,无需再对每一个对象都实现clone方法,但只能做到对象浅拷贝。
|
||||
|
||||
|
||||
CAS
|
||||
|
||||
Unsafe类的CAS操作为Java的锁机制提供了一种新的解决办法,比如AtomicInteger等类都是通过该方法来实现的。compareAndSwap*方法是原子的,可以避免繁重的锁机制,提高代码效率。
|
||||
|
||||
|
||||
|
||||
CAS一般用于乐观锁,它在Java中有广泛的应用,ReentrantLock、ConcurrentHashMap,ConcurrentLinkedQueue等都有用到CAS来实现乐观锁。
|
||||
|
||||
3.3、偏移量
|
||||
|
||||
Unsafe提供以下方法获取对象的指针,通过对指针进行偏移,不仅可以直接修改指针指向的数据(即使它们是私有的),甚至可以找到JVM已经认定为垃圾、可以进行回收的对象。
|
||||
|
||||
|
||||
|
||||
// 获取静态属性Field在对象中的偏移量,读写静态属性时必须获取其偏移量
|
||||
public native long staticFieldOffset(Field var1);
|
||||
// 获取非静态属性Field在对象实例中的偏移量,读写对象的非静态属性时会用到这个偏移量
|
||||
public native long objectFieldOffset(Field var1);
|
||||
// 返回Field所在的对象
|
||||
public native Object staticFieldBase(Field var1);
|
||||
// 返回数组中第一个元素实际地址相对整个数组对象的地址的偏移量
|
||||
public native int arrayBaseOffset(Class<?> var1);
|
||||
// 计算数组中第一个元素所占用的内存空间
|
||||
public native int arrayIndexScale(Class<?> var1);
|
||||
|
||||
3.4、线程调度
|
||||
|
||||
// 唤醒线程
|
||||
public native void unpark(Object var1);
|
||||
|
||||
// 挂起线程
|
||||
public native void park(boolean var1, long var2);
|
||||
|
||||
// 用于加锁,已废弃
|
||||
public native void monitorEnter(Object var1);
|
||||
|
||||
// 用于加锁,已废弃
|
||||
public native void monitorExit(Object var1);
|
||||
|
||||
// 用于加锁,已废弃
|
||||
public native boolean tryMonitorEnter(Object var1);
|
||||
|
||||
通过park方法将线程进行挂起, 线程将一直阻塞到超时或中断条件出现。unpark方法可以终止一个挂起的线程,使其恢复正常。
|
||||
|
||||
整个并发框架中对线程的挂起操作被封装在LockSupport类中,LockSupport类中有各种版本park方法,但最终都调用了Unsafe.park()方法。
|
||||
|
||||
3.5、类加载
|
||||
|
||||
// 方法定义一个类,用于动态地创建类
|
||||
public native Class<?> defineClass(String var1, byte[] var2, int var3, int var4, ClassLoader var5, ProtectionDomain var6);
|
||||
|
||||
// 动态的创建一个匿名内部类
|
||||
public native Class<?> defineAnonymousClass(Class<?> var1, byte[] var2, Object[] var3);
|
||||
|
||||
// 判断是否需要初始化一个类
|
||||
public native boolean shouldBeInitialized(Class<?> var1);
|
||||
|
||||
// 保证已经初始化过一个类
|
||||
public native void ensureClassInitialized(Class<?> var1);
|
||||
|
||||
3.6、内存屏障
|
||||
|
||||
// 保证在这个屏障之前的所有读操作都已经完成
|
||||
public native void loadFence();
|
||||
|
||||
// 保证在这个屏障之前的所有写操作都已经完成
|
||||
public native void storeFence();
|
||||
|
||||
// 保证在这个屏障之前的所有读写操作都已经完成
|
||||
public native void fullFence();
|
||||
|
||||
3.7、非常规对象实例化
|
||||
|
||||
通常,我们通过new或反射来实例化对象,而Unsafe类提供的allocateInstance方法,可以直接生成对象实例,且无需调用构造方法和其他初始化方法;这在对象反序列化的时候会很有用,能够重建和设置final字段,而不需要调用构造方法。
|
||||
|
||||
3.8、数组操作
|
||||
|
||||
|
||||
|
||||
arrayBaseOffset(获取数组第一个元素的偏移地址)与arrayIndexScale(获取数组中元素的增量地址)配合起来使用,就可以定位数组中每个元素在内存中的位置。
|
||||
|
||||
由于Java的数组最大值为Integer.MAX_VALUE,使用Unsafe类的内存分配方法可以实现超大数组。实际上这样的数据就可以认为是C数组,因此需要注意在合适的时间释放内存。
|
||||
|
||||
3.9、其他
|
||||
|
||||
当然,Unsafe类中还提供了大量其他的方法,比如上面提到的CAS操作,以AtomicInteger为例,当我们调用getAndIncrement、getAndDecrement等方法时,本质上调用的就是Unsafe的getAndAddInt方法。
|
||||
|
||||
如下为两个系统相关的方法:
|
||||
|
||||
// 返回系统指针的大小。返回值为4(32位系统)或 8(64位系统)。
|
||||
|
||||
public native int addressSize();
|
||||
|
||||
// 内存页的大小,此值为2的幂次方。
|
||||
|
||||
public native int pageSize();
|
||||
|
||||
3.10、结语
|
||||
|
||||
在实践的过程中,如果阅读其他框架或类库实现,当发现用到Unsafe类,可对照该类的整体功能,结合应用场景进行分析,即可大概了解其功能。
|
||||
BIN
Java基础教程/Java标准库/image/2023-03-13-10-53-12.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
Java基础教程/Java标准库/image/2023-03-13-10-54-08.png
Normal file
|
After Width: | Height: | Size: 154 KiB |
8
Java基础教程/Java语言基础/23 native方法.md
Normal file
@@ -0,0 +1,8 @@
|
||||
https://blog.csdn.net/weixin_43653599/article/details/111592025
|
||||
|
||||
https://www.jianshu.com/p/21f7ebb9e63f
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,9 +35,70 @@ arguments:一到多个参数。
|
||||
```shell
|
||||
转义序列:除了支持printf(1)和printf(3)的转义序列,内建printf还支持以下转义序列:
|
||||
|
||||
%b 展开参数中的反斜杠转义字符。
|
||||
# 常用转义字符
|
||||
\" - 转义后的双引号
|
||||
\\ - 转义后的反斜杠
|
||||
\b - 退格符,后退
|
||||
\n - 换行符,换行
|
||||
\r - 回车符,回车
|
||||
\t - 水平制表符
|
||||
\v - 垂直制表符
|
||||
\a 警告字符,通常为ASCII的BEL字符
|
||||
\f 换页
|
||||
\ 表示\本身
|
||||
|
||||
|
||||
# 常用类型转换字符
|
||||
|
||||
%d,%i 十进制整数
|
||||
%f - 将参数打印为浮点数
|
||||
%s - 将参数打印为字符串
|
||||
%x - 将参数打印为十六进制整数
|
||||
%o - 将参数打印为八进制整数
|
||||
%b - 相对应的参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符会被转义
|
||||
%c ASCII字符,即显示对应参数的第一个字符
|
||||
%u 不带正负号的十进制值
|
||||
%x 十六进制值(a-f)
|
||||
%X 十六进制值(A-F)
|
||||
%% 表示%本身
|
||||
%q 将参数扩起以用作shell输入。
|
||||
%(fmt)T 根据strftime(3)中的转义字符来输出日期时间字符串。
|
||||
|
||||
|
||||
|
||||
\003设置字符
|
||||
|
||||
背景和字体颜色
|
||||
|
||||
字背景颜色范围: 40–49 字颜色: 30–39
|
||||
40: 黑 30: 黑
|
||||
41: 红 31: 红
|
||||
42: 绿 32: 绿
|
||||
43: 黄 33: 黄
|
||||
44: 蓝 34: 蓝
|
||||
45: 紫 35: 紫
|
||||
46: 深绿 36: 深绿
|
||||
47: 白色 37: 白色
|
||||
|
||||
\033[0m 关闭所有属性
|
||||
\033[1m 设置高亮度
|
||||
\033[4m 下划线
|
||||
\033[5m 闪烁
|
||||
\033[7m 反显
|
||||
\033[8m 消隐
|
||||
\033[30m – \033[37m 设置前景色
|
||||
\033[40m – \033[47m 设置背景色
|
||||
\033[nA 光标上移n行
|
||||
\033[nB 光标下移n行
|
||||
\033[nC 光标右移n行
|
||||
\033[nD 光标左移n行
|
||||
\033[y;xH设置光标位置
|
||||
\033[2J 清屏
|
||||
\033[K 清除从光标到行尾的内容
|
||||
\033[s 保存光标位置
|
||||
\033[u 恢复光标位置
|
||||
\033[?25l 隐藏光标
|
||||
\033[?25h 显示光标
|
||||
```
|
||||
|
||||
#### 返回值
|
||||
@@ -187,3 +248,22 @@ value1
|
||||
的`Description`段落。
|
||||
|
||||
|
||||
|
||||
### 一个刷新显示的脚本实例
|
||||
```sh
|
||||
#!/bin/bash
|
||||
# 当Ctrl+c 清空屏幕再退出,见引用3
|
||||
trap "clear;exit" 2
|
||||
# 翻一个新屏幕
|
||||
clear
|
||||
# 每秒刷新输出屏幕的端口统计结果
|
||||
while [ true ]
|
||||
do
|
||||
# 需要执行的功能命令,各写各的业务
|
||||
report=`$*`
|
||||
# 使用ASCI码控制光标定位回到第一行第一列,见引用1
|
||||
printf "\033[1;1H%s" $report
|
||||
# 进程睡眠1秒
|
||||
sleep 1
|
||||
done
|
||||
```
|
||||
414
test5.csv
Normal file
@@ -0,0 +1,414 @@
|
||||
10.111.51.108,24
|
||||
10.111.67.138,24
|
||||
10.111.67.137,24
|
||||
10.111.50.3,24
|
||||
10.111.67.70,24
|
||||
10.111.67.71,24
|
||||
10.111.164.139,24
|
||||
10.111.67.132,24
|
||||
10.111.67.131,24
|
||||
10.111.164.137,24
|
||||
10.111.67.75,24
|
||||
10.111.67.72,24
|
||||
10.111.164.135,24
|
||||
10.111.164.136,24
|
||||
10.111.67.73,24
|
||||
10.111.51.101,24
|
||||
10.111.51.103,24
|
||||
10.111.51.104,24
|
||||
10.111.51.100,24
|
||||
10.111.68.171,24
|
||||
10.111.51.116,24
|
||||
10.111.164.2,24
|
||||
10.111.68.172,24
|
||||
10.111.51.119,24
|
||||
10.111.67.56,24
|
||||
10.111.67.57,24
|
||||
10.111.67.54,24
|
||||
10.111.67.55,24
|
||||
10.111.67.145,24
|
||||
10.111.164.9,24
|
||||
10.111.67.147,24
|
||||
10.111.67.58,24
|
||||
10.111.67.146,24
|
||||
10.111.67.59,24
|
||||
10.111.164.128,24
|
||||
10.111.67.143,24
|
||||
10.111.67.142,24
|
||||
10.111.67.63,24
|
||||
10.111.67.64,24
|
||||
10.111.164.127,24
|
||||
10.111.67.62,24
|
||||
10.111.164.123,24
|
||||
10.111.51.113,24
|
||||
10.111.51.114,24
|
||||
10.111.164.121,24
|
||||
10.111.68.160,24
|
||||
10.111.67.46,24
|
||||
10.111.67.49,24
|
||||
10.111.67.47,24
|
||||
10.111.67.48,24
|
||||
10.111.164.118,24
|
||||
10.111.67.52,24
|
||||
10.111.164.115,24
|
||||
10.111.164.116,24
|
||||
10.111.67.53,24
|
||||
10.111.67.51,24
|
||||
10.111.164.114,24
|
||||
10.111.68.167,24
|
||||
10.111.68.166,24
|
||||
10.111.68.153,24
|
||||
10.111.68.152,24
|
||||
10.111.68.151,24
|
||||
10.111.67.34,24
|
||||
10.111.67.35,24
|
||||
10.111.67.32,24
|
||||
10.111.67.33,24
|
||||
10.111.67.38,24
|
||||
10.111.67.39,24
|
||||
10.111.67.36,24
|
||||
10.111.67.37,24
|
||||
10.111.164.107,24
|
||||
10.111.67.42,24
|
||||
10.111.67.40,24
|
||||
10.111.68.157,24
|
||||
10.111.164.100,24
|
||||
10.111.68.156,24
|
||||
10.111.68.155,24
|
||||
10.111.68.154,24
|
||||
10.111.68.159,24
|
||||
10.111.68.158,24
|
||||
10.111.66.254,24
|
||||
10.111.164.180,24
|
||||
10.111.66.253,24
|
||||
10.111.67.29,24
|
||||
10.111.66.251,24
|
||||
10.111.67.23,24
|
||||
10.111.67.24,24
|
||||
10.111.67.21,24
|
||||
10.111.67.22,24
|
||||
10.111.67.27,24
|
||||
10.111.67.28,24
|
||||
10.111.67.25,24
|
||||
10.111.67.26,24
|
||||
10.111.67.174,24
|
||||
10.111.67.170,24
|
||||
10.111.65.217,24
|
||||
10.111.67.30,24
|
||||
10.111.65.216,24
|
||||
10.111.67.31,24
|
||||
10.111.67.171,24
|
||||
10.111.66.255,24
|
||||
10.111.50.236,24
|
||||
10.111.50.235,24
|
||||
10.111.67.16,24
|
||||
10.111.65.222,24
|
||||
10.111.65.221,24
|
||||
10.111.67.15,24
|
||||
10.111.65.224,24
|
||||
10.111.65.223,24
|
||||
10.111.67.184,24
|
||||
10.111.65.226,24
|
||||
10.111.67.186,24
|
||||
10.111.65.225,24
|
||||
10.111.65.228,24
|
||||
10.111.65.227,24
|
||||
10.111.67.183,24
|
||||
10.111.65.229,24
|
||||
10.111.67.182,24
|
||||
10.111.51.129,24
|
||||
10.111.67.156,24
|
||||
10.111.67.155,24
|
||||
10.111.67.157,24
|
||||
10.111.67.154,24
|
||||
10.111.51.123,24
|
||||
10.111.51.124,24
|
||||
10.111.51.125,24
|
||||
10.111.68.196,24
|
||||
10.111.68.195,24
|
||||
10.111.67.167,24
|
||||
10.111.67.166,24
|
||||
10.111.67.169,24
|
||||
10.111.67.168,24
|
||||
10.111.67.163,24
|
||||
10.111.67.165,24
|
||||
10.111.67.164,24
|
||||
10.111.65.206,24
|
||||
10.111.65.205,24
|
||||
10.111.65.208,24
|
||||
10.111.65.207,24
|
||||
10.111.164.145,24
|
||||
10.111.164.140,24
|
||||
10.111.51.130,24
|
||||
10.111.51.131,24
|
||||
10.111.164.141,24
|
||||
10.111.51.132,24
|
||||
10.111.164.47,24
|
||||
10.111.164.46,24
|
||||
10.111.169.246,24
|
||||
10.111.169.242,24
|
||||
10.111.68.109,24
|
||||
10.111.68.108,24
|
||||
10.111.68.107,24
|
||||
10.111.169.248,24
|
||||
10.111.68.228,24
|
||||
10.111.68.102,24
|
||||
10.111.68.225,24
|
||||
10.111.68.101,24
|
||||
10.111.68.226,24
|
||||
10.111.68.227,24
|
||||
10.111.68.220,24
|
||||
10.111.68.106,24
|
||||
10.111.68.221,24
|
||||
10.111.68.105,24
|
||||
10.111.68.222,24
|
||||
10.111.68.104,24
|
||||
10.111.68.103,24
|
||||
10.111.68.223,24
|
||||
10.111.164.58,24
|
||||
10.111.164.59,24
|
||||
10.111.169.251,24
|
||||
10.111.169.252,24
|
||||
10.111.169.253,24
|
||||
10.111.68.217,24
|
||||
10.111.68.218,24
|
||||
10.111.68.219,24
|
||||
10.111.68.213,24
|
||||
10.111.68.215,24
|
||||
10.111.68.216,24
|
||||
10.111.68.210,24
|
||||
10.111.68.211,24
|
||||
10.111.68.212,24
|
||||
10.111.164.22,24
|
||||
10.111.164.23,24
|
||||
10.111.68.206,24
|
||||
10.111.68.207,24
|
||||
10.111.68.208,24
|
||||
10.111.164.29,24
|
||||
10.111.51.94,24
|
||||
10.111.164.197,24
|
||||
10.111.51.95,24
|
||||
10.111.164.198,24
|
||||
10.111.68.205,24
|
||||
10.111.164.195,24
|
||||
10.111.164.196,24
|
||||
10.111.51.97,24
|
||||
10.111.68.201,24
|
||||
10.111.164.191,24
|
||||
10.111.164.32,24
|
||||
10.111.164.190,24
|
||||
10.111.164.31,24
|
||||
10.111.164.34,24
|
||||
10.111.164.185,24
|
||||
10.111.96.155,24
|
||||
10.111.96.153,24
|
||||
10.111.6.8,24
|
||||
10.111.51.81,24
|
||||
10.111.96.150,24
|
||||
10.111.169.201,24
|
||||
10.111.68.145,24
|
||||
10.111.68.144,24
|
||||
10.111.68.143,24
|
||||
10.111.96.159,24
|
||||
10.111.96.145,24
|
||||
10.111.164.14,24
|
||||
10.111.51.90,24
|
||||
10.111.68.131,24
|
||||
10.111.96.143,24
|
||||
10.111.68.130,24
|
||||
10.111.164.13,24
|
||||
10.111.169.213,24
|
||||
10.111.67.101,24
|
||||
10.111.67.100,24
|
||||
10.111.169.218,24
|
||||
10.111.68.135,24
|
||||
10.111.68.134,24
|
||||
10.111.51.82,24
|
||||
10.111.68.133,24
|
||||
10.111.68.132,24
|
||||
10.111.68.139,24
|
||||
10.111.68.138,24
|
||||
10.111.96.148,24
|
||||
10.111.51.89,24
|
||||
10.111.68.137,24
|
||||
10.111.96.149,24
|
||||
10.111.68.136,24
|
||||
10.111.68.241,24
|
||||
10.111.68.120,24
|
||||
10.111.68.129,24
|
||||
10.111.68.124,24
|
||||
10.111.68.246,24
|
||||
10.111.68.247,24
|
||||
10.111.68.121,24
|
||||
10.111.96.137,24
|
||||
10.111.96.138,24
|
||||
10.111.68.245,24
|
||||
10.111.163.24,24
|
||||
10.111.67.209,24
|
||||
10.111.67.202,24
|
||||
10.111.68.119,24
|
||||
10.111.68.118,24
|
||||
10.111.68.235,24
|
||||
10.111.68.113,24
|
||||
10.111.68.112,24
|
||||
10.111.68.236,24
|
||||
10.111.68.237,24
|
||||
10.111.68.111,24
|
||||
10.111.68.238,24
|
||||
10.111.68.110,24
|
||||
10.111.68.117,24
|
||||
10.111.68.231,24
|
||||
10.111.68.116,24
|
||||
10.111.68.115,24
|
||||
10.111.68.114,24
|
||||
10.111.68.234,24
|
||||
10.111.23.212,24
|
||||
10.111.6.74,24
|
||||
10.111.167.232,24
|
||||
10.111.23.213,24
|
||||
10.111.167.235,24
|
||||
10.111.23.215,24
|
||||
10.111.96.194,24
|
||||
10.111.96.191,24
|
||||
10.111.96.190,24
|
||||
10.111.167.230,24
|
||||
10.111.96.188,24
|
||||
10.111.96.185,24
|
||||
10.111.167.229,24
|
||||
10.111.96.179,24
|
||||
10.111.96.177,24
|
||||
10.111.96.178,24
|
||||
10.111.96.174,24
|
||||
10.111.169.185,24
|
||||
10.111.23.202,24
|
||||
10.111.169.194,24
|
||||
10.111.162.186,24
|
||||
10.111.169.195,24
|
||||
10.111.96.164,24
|
||||
10.111.167.248,24
|
||||
10.111.23.203,24
|
||||
10.111.96.163,24
|
||||
10.111.169.191,24
|
||||
10.111.23.204,24
|
||||
10.111.96.160,24
|
||||
10.111.96.161,24
|
||||
10.111.23.207,24
|
||||
10.111.23.208,24
|
||||
10.111.164.88,24
|
||||
10.111.164.83,24
|
||||
10.111.164.84,24
|
||||
10.111.164.98,24
|
||||
10.111.164.99,24
|
||||
10.111.164.96,24
|
||||
10.111.164.97,24
|
||||
10.111.164.91,24
|
||||
10.111.164.94,24
|
||||
10.111.164.95,24
|
||||
10.111.164.92,24
|
||||
10.111.67.0,24
|
||||
10.111.67.4,24
|
||||
10.111.67.6,24
|
||||
10.111.67.5,24
|
||||
10.111.67.8,24
|
||||
10.111.67.7,24
|
||||
10.111.67.9,24
|
||||
10.111.167.210,24
|
||||
10.111.167.213,24
|
||||
10.111.167.214,24
|
||||
10.111.164.67,24
|
||||
10.111.167.216,24
|
||||
10.111.164.60,24
|
||||
10.111.167.218,24
|
||||
10.111.167.219,24
|
||||
10.111.164.76,24
|
||||
10.111.164.74,24
|
||||
10.111.167.200,24
|
||||
10.111.167.201,24
|
||||
10.111.167.202,24
|
||||
10.111.164.78,24
|
||||
10.111.167.204,24
|
||||
10.111.164.73,24
|
||||
10.111.167.206,24
|
||||
10.111.167.207,24
|
||||
10.111.167.208,24
|
||||
10.111.167.209,24
|
||||
10.111.167.198,24
|
||||
10.111.170.44,24
|
||||
10.111.167.190,24
|
||||
10.111.167.196,24
|
||||
10.111.167.197,24
|
||||
10.111.170.42,24
|
||||
10.111.170.43,24
|
||||
10.111.167.187,24
|
||||
10.111.167.188,24
|
||||
10.111.167.189,24
|
||||
10.111.170.27,24
|
||||
10.111.50.247,24
|
||||
10.111.50.248,24
|
||||
10.111.50.246,24
|
||||
10.111.65.231,24
|
||||
10.111.50.243,24
|
||||
10.111.50.244,24
|
||||
10.111.65.230,24
|
||||
10.111.50.242,24
|
||||
10.111.65.234,24
|
||||
10.111.50.249,24
|
||||
client_address,24
|
||||
10.111.50.250,24
|
||||
10.111.170.35,24
|
||||
10.111.170.33,24
|
||||
10.111.170.34,24
|
||||
10.111.68.88,24
|
||||
10.111.68.89,24
|
||||
10.111.68.94,24
|
||||
10.111.68.95,24
|
||||
10.111.68.96,24
|
||||
10.111.68.90,24
|
||||
10.111.68.77,24
|
||||
10.111.68.82,24
|
||||
10.111.68.83,24
|
||||
10.111.22.81,24
|
||||
10.111.68.87,24
|
||||
10.111.22.80,24
|
||||
10.111.68.84,24
|
||||
10.111.170.13,24
|
||||
10.111.170.11,24
|
||||
10.111.68.67,24
|
||||
10.111.68.71,24
|
||||
10.111.22.73,24
|
||||
10.111.68.72,24
|
||||
10.111.68.75,24
|
||||
10.111.68.76,24
|
||||
10.111.164.201,24
|
||||
10.111.68.74,24
|
||||
10.111.164.202,24
|
||||
10.111.164.200,24
|
||||
10.111.167.176,24
|
||||
10.111.167.177,24
|
||||
10.111.23.199,24
|
||||
10.111.68.57,24
|
||||
10.111.68.58,24
|
||||
10.111.68.56,24
|
||||
10.111.167.173,24
|
||||
10.111.68.59,24
|
||||
10.111.167.174,24
|
||||
10.111.167.175,24
|
||||
10.111.68.60,24
|
||||
10.111.68.61,24
|
||||
10.111.68.64,24
|
||||
10.111.68.65,24
|
||||
10.111.68.62,24
|
||||
10.111.67.78,24
|
||||
10.111.68.46,24
|
||||
10.111.67.79,24
|
||||
10.111.68.47,24
|
||||
10.111.67.76,24
|
||||
10.111.67.77,24
|
||||
10.111.68.45,24
|
||||
10.111.68.48,24
|
||||
10.111.67.80,24
|
||||
10.111.68.53,24
|
||||
10.111.68.54,24
|
||||
10.111.67.175,23
|
||||
10.111.164.3,20
|
||||
10.111.164.33,1
|
||||
|
@@ -67,6 +67,8 @@ TCP首部,它通常是20个字节。
|
||||
* CLOSED状态不是一个真正的状态,而是这个状态图的假想起点和终点。
|
||||
* 只有当SYN_RCVD状态是从LISTEN状态(正常情况)进入,而不是从SYN_SENT状态(同时打开)进入时,从SYN_RCVD回到LISTEN的状态变迁才是有效的。这意味着如果我们执行被动关闭(进入LISTEN),收到一个SYN,发送一个带ACK的SYN(进入SYN_RCVD),然后收到一个RST,而不是一个ACK,便又回到LISTEN状态并等待另一个连接请求的到来。
|
||||
|
||||

|
||||
|
||||
### 状态迁移图说明
|
||||
1. 2MSL等待状态
|
||||
|
||||
@@ -153,3 +155,46 @@ RST标志表示复位,用来复位连接。
|
||||
* RST的接收方会区分另一端执行的是异常关闭还是正常关闭。并可以通知应用程序。
|
||||
|
||||
|
||||
### TimeWait状态
|
||||
https://zhuanlan.zhihu.com/p/523678245
|
||||
|
||||
主动关闭放
|
||||
|
||||
如果我们来做个类比的话,TIME_WAIT的出现,对应的是你的程序里的异常处理,它的出现,就是为了解决网络的丢包和网络不稳定所带来的其他问题:
|
||||
|
||||
第一,防止前一个连接【五元组,我们继续以 180.172.35.150:45678, tcp, 180.97.33.108:80 为例】上延迟的数据包或者丢失重传的数据包,被后面复用的连接【前一个连接关闭后,此时你再次访问百度,新的连接可能还是由180.172.35.150:45678, tcp, 180.97.33.108:80 这个五元组来表示,也就是源端口凑巧还是45678】错误的接收(异常:数据丢了,或者传输太慢了),参见下图:
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
SEQ=3的数据包丢失,重传第一次,没有得到ACK确认
|
||||
如果没有TIME_WAIT,或者TIME_WAIT时间非常端,那么关闭的连接【180.172.35.150:45678, tcp, 180.97.33.108:80 的状态变为了CLOSED,源端口可被再次利用】,马上被重用【对180.97.33.108:80新建的连接,复用了之前的随机端口45678】,并连续发送SEQ=1,2 的数据包
|
||||
此时,前面的连接上的SEQ=3的数据包再次重传,同时,seq的序号刚好也是3(这个很重要,不然,SEQ的序号对不上,就会RST掉),此时,前面一个连接上的数据被后面的一个连接错误的接收
|
||||
第二,确保连接方能在时间范围内,关闭自己的连接。其实,也是因为丢包造成的,参见下图:
|
||||
|
||||

|
||||
|
||||
主动关闭方关闭了连接,发送了FIN;
|
||||
被动关闭方回复ACK同时也执行关闭动作,发送FIN包;此时,被动关闭的一方进入LAST_ACK状态
|
||||
主动关闭的一方回去了ACK,主动关闭一方进入TIME_WAIT状态;
|
||||
但是最后的ACK丢失,被动关闭的一方还继续停留在LAST_ACK状态
|
||||
此时,如果没有TIME_WAIT的存在,或者说,停留在TIME_WAIT上的时间很短,则主动关闭的一方很快就进入了CLOSED状态,也即是说,如果此时新建一个连接,源随机端口如果被复用,在connect发送SYN包后,由于被动方仍认为这条连接【五元组】还在等待ACK,但是却收到了SYN,则被动方会回复RST
|
||||
造成主动创建连接的一方,由于收到了RST,则连接无法成功
|
||||
所以,你看到了,TIME_WAIT的存在是很重要的,如果强制忽略TIME_WAIT,还是有很高的机率,造成数据粗乱,或者短暂性的连接失败。
|
||||
|
||||
|
||||
### CloseWait
|
||||
被动关闭方。
|
||||
|
||||
CLOSE_WAIT才可怕,因为CLOSE_WAIT很多,表示说要么是你的应用程序写的有问题,没有合适的关闭socket;要么是说,你的服务器CPU处理不过来(CPU太忙)或者你的应用程序一直睡眠到其它地方(锁,或者文件I/O等等),你的应用程序获得不到合适的调度时间,造成你的程序没法真正的执行close操作。
|
||||
|
||||
|
||||
### 关于主动关闭和被动关闭的讨论
|
||||
请求的发起方和接收方都可能主动关闭或者被动关闭。与请求发出方和接收方无关。
|
||||
|
||||
例如,服务器响应超时,客户端等不及了,会触发超时时间主动关闭,此时虽然服务器收到了fin包,并且协议层可以返回ack进行确认,进入了closewait状态。但是服务器因为还在处理超时的任务,肯定要继续等待任务处理完成才会调用close函数,主动关闭。
|
||||
|
||||
|
||||
|
||||
BIN
计算机网络/image/2023-03-10-14-11-26.png
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
计算机网络/image/2023-03-10-14-25-57.png
Normal file
|
After Width: | Height: | Size: 683 KiB |
BIN
计算机网络/image/2023-03-10-14-26-19.png
Normal file
|
After Width: | Height: | Size: 483 KiB |