「深度学习福利」大神带你进阶工程师,立即查看>>>
awt.toolkit | sun.awt.X11.XToolkit file.encoding.pkg | sun.io |
---|
java.specification.version | 1.8 | sun.cpu.isalist | | sun.jnu.encoding | ANSI_X3.4-1968 | com.sun.jndi.ldap.connect.pool.maxsize | 0 | java.class.path | /opt/atlassian/confluence/bin/bootstrap.jar /opt/atlassian/confluence/bin/tomcat-juli.jar | java.vm.vendor | Oracle Corporation | plugin.webresource.javascript.try.catch.wrapping | true | sun.arch.data.model | 64 | sun.font.fontmanager | sun.awt.X11FontManager | catalina.useNaming | true | java.vendor.url | http://java.oracle.com/ | user.timezone | America/New_York | os.name | Linux | java.vm.specification.version | 1.8 | sun.java.launcher | SUN_STANDARD | user.country | US | atlassian.org.osgi.framework.bootdelegation.extra | org.apache.lucene.* | sun.boot.library.path | /opt/atlassian/confluence/jre/lib/amd64 | sun.java.command | org.apache.catalina.startup.Bootstrap start | sun.cpu.endian | little | user.home | /home/confluence | user.language | en | java.specification.vendor | Oracle Corporation | java.naming.factory.url.pkgs | org.apache.naming | java.home | /opt/atlassian/confluence/jre | ignore.endorsed.dirs | | atlassian.plugins.startup.options | | com.sun.jndi.ldap.connect.pool.protocol | plain ssl | file.separator | / | com.sun.jndi.ldap.connect.pool.initsize | 1 | atlassian.plugins.enable.wait | 300 | line.separator | | java.vm.specification.vendor | Oracle Corporation | java.specification.name | Java Platform API Specification | java.awt.graphicsenv | sun.awt.X11GraphicsEnvironment | java.awt.headless | true | package.access | sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat. | package.definition | sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.,org.apache.tomcat. | sun.boot.class.path | /opt/atlassian/confluence/jre/lib/resources.jar /opt/atlassian/confluence/jre/lib/rt.jar /opt/atlassian/confluence/jre/lib/sunrsasign.jar /opt/atlassian/confluence/jre/lib/jsse.jar /opt/atlassian/confluence/jre/lib/jce.jar /opt/atlassian/confluence/jre/lib/charsets.jar /opt/atlassian/confluence/jre/lib/jfr.jar /opt/atlassian/confluence/jre/classes | jdk.tls.ephemeralDHKeySize | 2048 | server.loader | | java.util.logging.config.file | /opt/atlassian/confluence/conf/logging.properties | java.protocol.handler.pkgs | org.apache.catalina.webresources | sun.management.compiler | HotSpot 64-Bit Tiered Compilers | com.sun.jndi.ldap.connect.pool.authentication | simple | com.sun.jndi.ldap.connect.pool.prefsize | 10 | java.runtime.version | 1.8.0_162-b12 | java.naming.factory.initial | org.apache.naming.java.javaURLContextFactory | user.name | confluence | path.separator | : | common.loader | "${catalina.base}/lib" "${catalina.base}/lib/*.jar" "${catalina.home}/lib" "${catalina.home}/lib/*.jar" | os.version | 3.14.32-xxxx-grs-ipv6-64 | java.endorsed.dirs | /opt/atlassian/confluence/jre/lib/endorsed | java.runtime.name | Java(TM) SE Runtime Environment | file.encoding | ANSI_X3.4-1968 | org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE | 32768 | confluence.context.path | | java.vm.name | Java HotSpot(TM) 64-Bit Server VM | synchrony.enable.xhr.fallback | true | java.vendor.url.bug | http://bugreport.sun.com/bugreport/ | java.io.tmpdir | /opt/atlassian/confluence/temp | tomcat.util.scan.StandardJarScanFilter.jarsToScan | log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar | catalina.home | /opt/atlassian/confluence | com.sun.jndi.ldap.connect.pool.timeout | 30000 | java.version | 1.8.0_162 | atlassian.enable.spring.strong.cache.bean.metadata.flush | true | tomcat.util.scan.StandardJarScanFilter.jarsToSkip | bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,websocket-api.jar,catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-storeconfig.jar,catalina-tribes.jar,jasper.jar,jasper-el.jar,ecj-*.jar,tomcat-api.jar,tomcat-util.jar,tomcat-util-scan.jar,tomcat-coyote.jar,tomcat-dbcp.jar,tomcat-jni.jar,tomcat-websocket.jar,tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,tomcat-jdbc.jar,tools.jar,commons-beanutils*.jar,commons-codec*.jar,commons-collections*.jar,commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,commons-logging*.jar,commons-math*.jar,commons-pool*.jar,jstl.jar,taglibs-standard-spec-*.jar,geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,ant.jar,ant-junit*.jar,aspectj*.jar,jmx.jar,h2*.jar,hibernate*.jar,httpclient*.jar,jmx-tools.jar,jta*.jar,log4j*.jar,mail*.jar,slf4j*.jar,xercesImpl.jar,xmlParserAPIs.jar,xml-apis.jar,junit.jar,junit-*.jar,ant-launcher.jar,cobertura-*.jar,asm-*.jar,dom4j-*.jar,icu4j-*.jar,jaxen-*.jar,jdom-*.jar,jetty-*.jar,oro-*.jar,servlet-api-*.jar,tagsoup-*.jar,xmlParserAPIs-*.jar,xom-*.jar | user.dir | /opt/atlassian/confluence/bin | atlassian.enable.spring.strong.cache.bean.metadata | true | os.arch | amd64 | java.vm.specification.name | Java Virtual Machine Specification | java.awt.printerjob | sun.print.PSPrinterJob | sun.os.patch.level | unknown | catalina.base | /opt/atlassian/confluence | shared.loader | | java.util.logging.manager | org.apache.juli.ClassLoaderLogManager | java.library.path | /usr/java/packages/lib/amd64 /usr/lib64 /lib64 /lib /usr/lib | java.vendor | Oracle Corporation | java.vm.info | mixed mode | java.vm.version | 25.162-b12 | hibernate.bytecode.use_reflection_optimizer | true | sun.java2d.opengl | true | sun.io.unicode.encoding | UnicodeLittle | java.ext.dirs | /opt/atlassian/confluence/jre/lib/ext /usr/java/packages/lib/ext tomcat.util.buf.StringCache.byte.enabled | java.class.version true | 52.0 | https://www.cwiki.us/display/CONF6ZH/Viewing+Site+Statistics 「深度学习福利」大神带你进阶工程师,立即查看>>> 介绍 ping是用来测试目的主机是否可达的一个程序 原理:向目的主机发送ICMP回显请求报文,并等待返回ICMP回显应答 ping客户端:发送回显请求的主机 ping服务端:被ping的主机 大部分TCP/IP实现都在内核中实现ping服务端 ICMP回显请求与应答 报文格式: 标识符:Unix采用进程id作为标识符。用来匹配ICMP回显请求与应答 序号:从0开始,每次回显请求都会+1。用来确认是否有分组丢失、重复、乱序 局域网内ping: 广域网内ping: 观察到出现高延迟和大量分组丢失情况 IP记录路由选项 作为IP首部中的选项字段,最长40字节。用来记录IP报文经过了哪些主机 通过 ping -R ,程序就会记录并使用IP记录路由选项 当经过一个路由器,它记录出口IP地址,当带该选项的回显应答回到源主机(发ping请求的主机),也会记录该主机的入口地址。通过该功能,可以发现实际路由过程中会频繁使用默认路由 IP记录路由选项的报文: code:IP选项类型。值7代表IP记录路由选项 len:选项总字节长度。值为39 ptr:存放下一个IP地址的位置。初始化值为4,每当加入一个IP,值+4,当值为40时代表已经记录9个IP,空间已满 通过这种方式记录路由过程的问题: 不是所有主机都支持该选项。现在大部分系统都支持 记录的IP有限。由于只有40字节来记录,除开记录元信息的,最多只能记录9个IP IP记录时间戳选项 作为IP首部中的选项字段,最长40字节。 IP记录时间戳选项的报文: code:IP选项类型:值0x44代表IP记录时间戳选项 len:选项总字节长度。值为36或40 ptr:存放下一个时间戳的位置 OF:4位溢出字段。当路由器没有空间追加时间戳时,就增加溢出字段的值 FL:4位标志字段。不同标志描述了时间戳部分该记录哪些东西 可用FL: 该方案的问题是: 通常标志3才有意义。标志0功能太弱,标志1会导致只能放4条记录,并且可能都不是自己关心的 标志3中指定了主机,但这些主机的时间戳可能并不准确 「深度学习福利」大神带你进阶工程师,立即查看>>> 这样添加golang就可以保存文件的时候自动格式化代码了
「深度学习福利」大神带你进阶工程师,立即查看>>> 介绍 ICMP通常被认为是IP层的组成部分。它用来传送差错报文以及一些需要注意的信息,通常被IP层、TCP层、UDP层使用,偶尔也被用户层使用 ICMP报文 ICMP报文是放在IP数据报中进行传输 报文格式如下: 类型:有15个值,描述不同类型ICMP报文 代码:类型只是一个粗略描述,代码才是一个具体描述 校验和:是整个ICMP报文的校验和,算法与IP首部校验和算法相同 类型+代码唯一确定了ICMP报文的描述 这几种情况不会产生ICMP差错报文: ICMP差错报文 目的地址是广播地址或多播地址的IP数据报 链路层广播的数据报 不是IP分片的第一片 源地址不是单个主机的数据报 ICMP地址掩码请求与应答 ICMP地址掩码请求用于无盘系统获取自己的子网掩码,与RARP请求获取IP类似 请求和应答的报文格式: 其中标识符和序列号是发送端自定义,这些信息会随应答一起返回。发送端用这两个信息可以将请求和应答匹配起来 通过icmpaddrmask程序向目标地址发送ICMP地址掩码请求,其中140.252.13.63为子网内的广播地址 其中svr4返回的地址是错误的 向本机发送请求 其中响应的子网掩码是收到请求的接口的子网掩码,其中两个IP地址最后都是本机的环回接口处理,所以子网掩码就是127.0.0.1的 ICMP时间戳请求与应答 ICMP时间戳请求返回值是自午夜开始计算的毫秒数,利用ICMP时间戳请求,可以校正本机时间 请求与应答报文格式为: 发起时间戳:请求端填写,然后发送报文 接收时间戳:响应端接收到报文时填写 传送时间戳:响应端发送应答时填写 大部分系统后两者的值是一样的 向主机bsdi发送ICMP时间戳请求 其中有几点值得注意: 接收时间戳与传送时间戳一致 发送时间戳代表本机上的时间戳,可能需要被校准 rtt是请求往返时间,rtt/2约等于请求或应答的传输时间 difference = 接收时间戳 - 发起时间戳 sun主机需要调整本机时间 = 发起时间戳 + difference - rtt/2 ICMP端口不可达差错 当目的端口没有提供访问服务,就会报ICMP端口不可达差错 ICMP不可达报文格式: ICMP端口不可达差错代码为3 当发送UDP数据报,但目的端口不存在,目的主机返回的报文格式: 产生差错的数据报IP首部:之所以要返回这个信息,是因为只有知道该信息,才能了解IP上层协议是什么(TCP/UDP),如何解析它 UDP首部(TCP类似):UDP首部刚好8字节,只有知道UDP首部,才能获取源端口和目的端口,然后给调用方返回足够的信息 ICMP报文的4.4BSD处理 针对ICMP报文,4.4BSD系统的处理方式:
「深度学习福利」大神带你进阶工程师,立即查看>>> 一:MongoVUE无法创建collections Mongodb新的存储引擎为wiredTiger ,在这种存储引擎下面,我们用可视化工具MongoVUE是无法看到collection的应该更换为mmapv1引擎 1、删除data文件夹,然后重新创建data 2、紧接着执行mongod --storageEngine mmapv1 --dbpath D:\office\MongoDB\data 二:MongoVUE无法使用用户名密码登录 mongodb的认证机制有2种:SCRAM-SHA-1和MONGODB-CR。3.0之后版本默认为:SCRAM-SHA-1; 2、spring-mongodb默认为:MONGODB-CR,并不支持设置认证方式; 解决方法: 修改mongodb的认证方式即可。 1、查看auth认证方式 use admin db.system.version.findOne({"_id":"authSchema"}) (返回 { "_id" : "authSchema", "currentVersion" : 3 } currentVersion 3:MONGODB-CR currentVersion 5:SCRAM-SHA-1) 2、删除之前设置的所有用户 db.system.users.remove({}) 3、删除原auth认证方式,并设置为MONGODB-CR db.system.version.remove({}) db.system.version.insert({"_id":"authSchema","currentVersion":3}) 4、重新添加admin用户(超级管理员) use admin db.createUser({user:"admin",pwd:"admin",roles:[{role:"readWriteAnyDatabase",db:"admin"}]}) 5、新建test数据库,并为test数据库设置用户及角色(权限) use test db.createUser({user:"test",pwd:"test",roles:[{role:"dbOwner",db:"test"}]}) 三:admin库不能查看collections 将角色改为readWriteAnyDatabase db.updateUser("root",{roles:[{role:"readWriteAnyDatabase",db:"admin"}]}) 四:开启用户验证 方式一:在命令行输入mongod --auth --logpath "D:\office\MongoDB\log.mongod.log" --dbpath "D:\office\MongoDB\data" --reinstall 方式二:在命令行输入mongod --dbpath "D:\office\MongoDB\data" --logpath "D:\office\MongoDB\log.mongod.log" --auth 五:关闭用户验证 mongod --logpath "D:\office\MongoDB\log.mongod.log" --dbpath "D:\office\MongoDB\data" --reinstall 七:忘记密码 一旦忘记admin密码 即可关闭用户验证 删除用户 重新创建 六:登录 1:mongo 2:use admin 3:db.auth("root","root") 「深度学习福利」大神带你进阶工程师,立即查看>>> 介绍 RARP用来将MAC地址解析成IP地址 有盘主机的网络配置:启动时,从硬盘中读取IP并配置即可 无盘主机的网络配置:启动时,从网卡拿到MAC地址,再解析成IP地址,并完成配置 RARP分组格式 与ARP分组基本一致,差别在于RARP请求op为3,应答op为4 并且与ARP一致的是,请求是广播,应答是单播 RARP示例 当网络存在RARP服务器时: RARP服务器会响应sun主机的IP地址,表示这是源MAC地址对应的IP地址 当网络上不存在RARP服务器时: 不断重试 「深度学习福利」大神带你进阶工程师,立即查看>>> 介绍 内核知道IP也无法将数据传送到目的地址,必须知道MAC地址才能传送,所以需要ARP将IP解析为MAC地址 请求流程 DNS将主机名解析为IP地址 用IP地址建立连接 用IP地址发送IP数据包 如果目的主机在本地网络,那么IP数据报可以直接发送过去;如果目的主机在远程网络,那么IP数据报先经过路由到达本地网络的下一站路由器,让它转发 ARP用于将IP地址转换为MAC地址 广播ARP请求到该以太网所有主机 目的主机ARP层收到广播请求,识别出IP地址与自己相同,则回答ARP应答,包含IP地址与MAC地址 收到ARP应答,就可以传送IP数据报 将IP数据报发送到目的主机 ARP高速缓存 为了保证ARP高效运行,每个主机都有ARP高速缓存,存放最近IP地址到MAC地址的映射记录,一般生存时间为20min ARP分组格式 ARP请求和应答采用相同的分组格式(下图数字单位为字节) 以太网目的地址全为1代表广播地址 帧类型:后面的数据类型,0x0806代表ARP请求或应答 硬件类型:硬件地址的类型,值为1代表以太网MAC地址 协议类型:硬件地址映射的协议地址类型,值为0x0800代表IP地址 硬件地址长度:值为6代表MAC地址长度为6字节 协议地址长度:值为4代表IP地址长度为4字节 op:四个操作类型,值1代表ARP请求,值2代表ARP应答,值3代表RARP请求,值4代表RARP应答 一个ARP请求,会将首部的以太网目的地址填为全1,表示发起一次广播,然后会将请求体中的目的以太网地址填为全0,预留出来让接收端填充 一个ARP相应,会将预留的目的以太网地址填为全0,然后将首部和请求体中的以太网目的地址和以太网源地址进行交换,并且将op改为2,发送回去 ARP请求是一次广播,ARP响应则是向请求源发起的一次单播 ARP示例 一次连接成功的ARP请求、响应 一次连接超时的ARP请求、响应 没有任何ARP以外的报文,并且超时时间指数退避 ARP代理 一个网络向另一个网络发送ARP请求的时候,中间路由器代理响应ARP请求,就叫ARP代理 常用场景是,很多网关设备支持将内网地址映射为公网地址,达到影藏内部网络的作用,这就利用了ARP代理:本来网关的实际IP为内网IP,但是需要提供公网访问IP,这时就需要开启ARP代理功能,接收目的IP为外网IP的ARP请求,并响应内网IP的MAC地址,以便将外网流量转发到内网 免费ARP 免费ARP就是主机发送ARP广播请求查找自己的IP地址。通常在系统在配置网络的时候执行 两个常用场景: 查找网络内是否存在IP冲突的主机。如果发送免费ARP,并且得到响应,说明网络内存在相同IP的主机 通知网络其他主机,本机的IP和MAC地址映射有所改变。如果主机更换网卡,MAC地址会改变,IP可能还是维持原状,这时广播一个免费ARP,可以通知其他主机自己的IP和MAC映射改变了,并让他们的ARP高速缓存及时更新 arp命令 -a显示ARP高速缓存所有内容,-d删除其中一项,-s增加一项内容(默认永久),pus和-s可以让系统开启ARP代理 「深度学习福利」大神带你进阶工程师,立即查看>>> 先看下xml文件,事实上Servlet3.0开始,就可以不用配置xml文件,可以段前声明的方式来完成,看博客中另一篇文章。这里还是暂时使用下xml配置文件: Demo1 index.html index.htm index.jsp default.html default.htm default.jsp RegisterServlet com.demo1.servlet.RegisterServlet RegisterServlet /register.html ErrorServlet com.demo1.servlet.ErrorServlet ErrorServlet /error.html SuccessServlet com.demo1.servlet.SuccessServlet SuccessServlet /success.html TestServlet com.demo1.servlet.TestServlet TestServlet /test.html LoginServlet com.demo1.servlet.LoginServlet LoginServlet /login.html MemberServlet com.demo1.servlet.MemberServlet MemberServlet /member.html 其中 Login.jsp: <%@page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> 登陆页面 欢迎您 还没注册?点击注册吧 注册页面 index.jsp: <%@page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> 注册页面 注册页面 您有账号?点击直接登录 该模块中,没有使用数据库,只是简单写了一个类来模仿数据库功能,User.java: package com.demo1.java; import java.util.HashMap; import java.util.Map; public class User { private Map userMap = new HashMap(); private static User user = null; private User(){ userMap.put("韩春", "123456##abcdefg@163.com"); } public static User getInstance(){ if(user == null){ user = new User(); } return user; } public MapgetUserMap(){ return userMap; } } 下面几个为Servet文件: RegisterServlet.java package com.demo1.servlet; import com.demo1.java.User; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class RegisterServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String userName = req.getParameter("userName"); String password = req.getParameter("password"); String conPassword = req.getParameter("conPassword"); String email = req.getParameter("email"); List errors = new ArrayList(); //装载错误信息 if(!isValidUsername(userName)){ errors.add("用户名为空或者已经存在"); } if(!isValidEmail(email)){ errors.add("无效的邮箱号码"); } if(isValidPassword(password, conPassword)){ errors.add("密码为空或者两次输入不一样"); } if(errors.isEmpty()){ User user = User.getInstance(); Map map = user.getUserMap(); map.put(userName, password+"##"+email); req.getRequestDispatcher("/success.html").forward(req, resp); }else{ req.setAttribute("errors", errors); req.getRequestDispatcher("/error.html").forward(req, resp); } } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } public boolean isValidUsername(String username){ User user = User.getInstance(); Map map = user.getUserMap(); if(username != null){ //暂时先这样改 这里是有问题的,不能很好地判断 return true; }else{ return false; } } public boolean isValidPassword(String password, String conPassword){ return password == null || conPassword == null || password.length() < 6 || !password.equals(conPassword); } public boolean isValidEmail(String email){ boolean flag = false; if(email == null || "".equals(email)){ flag = false; }else{ flag = email.matches("^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$"); } return flag; } } 错误处理ErrorServlet.java package com.demo1.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ErrorServlet extends HttpServlet { private static final long serialVersionUID = 1l; public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); PrintWriter out = resp.getWriter(); out.println(""); out.println(""); out.println(" 新会员增加失败"); out.println(" "); out.print("新会员增加失败 "); @SuppressWarnings("unchecked") List list = (List)req.getAttribute("errors"); if(list != null){ for(String str:list){ out.println(str + ""); } } out.println("返回注册页面 " ); //注意这边的解析!!! out.println(" "); out.println(""); out.flush(); out.close(); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } } 注册验证成功 SuccessServlet.java package com.demo1.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class SuccessServlet extends HttpServlet { @SuppressWarnings("unused") private static final long serivalVersionUID = 1L; public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); PrintWriter out = resp.getWriter(); out.println(""); out.println(""); out.println(" 新会员增加成功"); out.println(" "); out.print("新会员增加成功 "); out.println("返回登陆页面 " ); out.println(" "); out.println(""); out.flush(); out.close(); out.flush(); out.close(); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } } 登陆验证 LoginServlet.java package com.demo1.servlet; import java.io.IOException; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.demo1.java.User; public class LoginServlet extends HttpServlet { public static final long serialVervletUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userName = request.getParameter("userName"); String password = request.getParameter("password"); if(checkLogin(userName, password)){ request.getRequestDispatcher("/member.html").forward(request, response); }else{ response.sendRedirect("/Demo1/jsp/front/Login.jsp"); } } public boolean checkLogin(String userName, String password)throws NullPointerException{ User user = User.getInstance(); Map map = user.getUserMap(); if(userName != null && !"".equals(userName) && password != null && !"".equals(password)){ String[] arr = map.get(userName).split("##"); if(arr[0].equals(password)){ return true; } } return false; } } 最后是登陆成功的欢迎界面: package com.demo1.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MemberServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println(""); out.println(""); out.println(" Welcome"); out.println(" "); out.print("" + request.getParameter("userName")+ " 您好,欢迎您哦" + ""); out.println(" "); out.println(""); out.flush(); out.close(); } } 注册页面时这样的: 亲,如果您感觉本文有用,请点个赞再走吧✌(>‿◠)!! 「深度学习福利」大神带你进阶工程师,立即查看>>>
| awt.toolkit | sun.awt.X11.XToolkit file.encoding.pkg | sun.io |
---|
java.specification.version | 1.8 | sun.cpu.isalist | | sun.jnu.encoding | ANSI_X3.4-1968 | com.sun.jndi.ldap.connect.pool.maxsize | 0 | java.class.path | /opt/atlassian/confluence/bin/bootstrap.jar /opt/atlassian/confluence/bin/tomcat-juli.jar | java.vm.vendor | Oracle Corporation | plugin.webresource.javascript.try.catch.wrapping | true | sun.arch.data.model | 64 | sun.font.fontmanager | sun.awt.X11FontManager | catalina.useNaming | true | java.vendor.url | http://java.oracle.com/ | user.timezone | America/New_York | os.name | Linux | java.vm.specification.version | 1.8 | sun.java.launcher | SUN_STANDARD | user.country | US | atlassian.org.osgi.framework.bootdelegation.extra | org.apache.lucene.* | sun.boot.library.path | /opt/atlassian/confluence/jre/lib/amd64 | sun.java.command | org.apache.catalina.startup.Bootstrap start | sun.cpu.endian | little | user.home | /home/confluence | user.language | en | java.specification.vendor | Oracle Corporation | java.naming.factory.url.pkgs | org.apache.naming | java.home | /opt/atlassian/confluence/jre | ignore.endorsed.dirs | | atlassian.plugins.startup.options | | com.sun.jndi.ldap.connect.pool.protocol | plain ssl | file.separator | / | com.sun.jndi.ldap.connect.pool.initsize | 1 | atlassian.plugins.enable.wait | 300 | line.separator | | java.vm.specification.vendor | Oracle Corporation | java.specification.name | Java Platform API Specification | java.awt.graphicsenv | sun.awt.X11GraphicsEnvironment | java.awt.headless | true | package.access | sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat. | package.definition | sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.,org.apache.tomcat. | sun.boot.class.path | /opt/atlassian/confluence/jre/lib/resources.jar /opt/atlassian/confluence/jre/lib/rt.jar /opt/atlassian/confluence/jre/lib/sunrsasign.jar /opt/atlassian/confluence/jre/lib/jsse.jar /opt/atlassian/confluence/jre/lib/jce.jar /opt/atlassian/confluence/jre/lib/charsets.jar /opt/atlassian/confluence/jre/lib/jfr.jar /opt/atlassian/confluence/jre/classes | jdk.tls.ephemeralDHKeySize | 2048 | server.loader | | java.util.logging.config.file | /opt/atlassian/confluence/conf/logging.properties | java.protocol.handler.pkgs | org.apache.catalina.webresources | sun.management.compiler | HotSpot 64-Bit Tiered Compilers | com.sun.jndi.ldap.connect.pool.authentication | simple | com.sun.jndi.ldap.connect.pool.prefsize | 10 | java.runtime.version | 1.8.0_162-b12 | java.naming.factory.initial | org.apache.naming.java.javaURLContextFactory | user.name | confluence | path.separator | : | common.loader | "${catalina.base}/lib" "${catalina.base}/lib/*.jar" "${catalina.home}/lib" "${catalina.home}/lib/*.jar" | os.version | 3.14.32-xxxx-grs-ipv6-64 | java.endorsed.dirs | /opt/atlassian/confluence/jre/lib/endorsed | java.runtime.name | Java(TM) SE Runtime Environment | file.encoding | ANSI_X3.4-1968 | org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE | 32768 | confluence.context.path | | java.vm.name | Java HotSpot(TM) 64-Bit Server VM | synchrony.enable.xhr.fallback | true | java.vendor.url.bug | http://bugreport.sun.com/bugreport/ | java.io.tmpdir | /opt/atlassian/confluence/temp | tomcat.util.scan.StandardJarScanFilter.jarsToScan | log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar | catalina.home | /opt/atlassian/confluence | com.sun.jndi.ldap.connect.pool.timeout | 30000 | java.version | 1.8.0_162 | atlassian.enable.spring.strong.cache.bean.metadata.flush | true | tomcat.util.scan.StandardJarScanFilter.jarsToSkip | bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,websocket-api.jar,catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-storeconfig.jar,catalina-tribes.jar,jasper.jar,jasper-el.jar,ecj-*.jar,tomcat-api.jar,tomcat-util.jar,tomcat-util-scan.jar,tomcat-coyote.jar,tomcat-dbcp.jar,tomcat-jni.jar,tomcat-websocket.jar,tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,tomcat-jdbc.jar,tools.jar,commons-beanutils*.jar,commons-codec*.jar,commons-collections*.jar,commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,commons-logging*.jar,commons-math*.jar,commons-pool*.jar,jstl.jar,taglibs-standard-spec-*.jar,geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,ant.jar,ant-junit*.jar,aspectj*.jar,jmx.jar,h2*.jar,hibernate*.jar,httpclient*.jar,jmx-tools.jar,jta*.jar,log4j*.jar,mail*.jar,slf4j*.jar,xercesImpl.jar,xmlParserAPIs.jar,xml-apis.jar,junit.jar,junit-*.jar,ant-launcher.jar,cobertura-*.jar,asm-*.jar,dom4j-*.jar,icu4j-*.jar,jaxen-*.jar,jdom-*.jar,jetty-*.jar,oro-*.jar,servlet-api-*.jar,tagsoup-*.jar,xmlParserAPIs-*.jar,xom-*.jar | user.dir | /opt/atlassian/confluence/bin | atlassian.enable.spring.strong.cache.bean.metadata | true | os.arch | amd64 | java.vm.specification.name | Java Virtual Machine Specification | java.awt.printerjob | sun.print.PSPrinterJob | sun.os.patch.level | unknown | catalina.base | /opt/atlassian/confluence | shared.loader | | java.util.logging.manager | org.apache.juli.ClassLoaderLogManager | java.library.path | /usr/java/packages/lib/amd64 /usr/lib64 /lib64 /lib /usr/lib | java.vendor | Oracle Corporation | java.vm.info | mixed mode | java.vm.version | 25.162-b12 | hibernate.bytecode.use_reflection_optimizer | true | sun.java2d.opengl | true | sun.io.unicode.encoding | UnicodeLittle | java.ext.dirs | /opt/atlassian/confluence/jre/lib/ext /usr/java/packages/lib/ext tomcat.util.buf.StringCache.byte.enabled | java.class.version true | 52.0 | https://www.cwiki.us/display/CONF6ZH/Viewing+Site+Statistics 「深度学习福利」大神带你进阶工程师,立即查看>>> 当你添加了内存,设置了代理(proxy)或者修改了 Java 的选项,通常比较难判断系统是否已经按照你的修改进行了配置和启动。这个页面将会帮助你查看 Confluence 站点运行使用的系统属性。 你可以在 系统信息(System Information)界面中扩展系统的属性,这个配置是在 Confluence 的管理员控制台中配置。在查询系统信息之前,你不需要重新启动 Confluence 服务器。 希望查看有关你 Confluence 的系统属性: 在屏幕的右上角单击 控制台按钮 ,然后选择 General Configuration 链接。 在左侧面板中选择 系统信息(System Information) 。 滚动鼠标到下面的 系统属性(System Properties) 部分进行查看。 https://www.cwiki.us/display/CONF6ZH/Viewing+System+Properties 「深度学习福利」大神带你进阶工程师,立即查看>>> 最近公司的微服务maven分模块一个父工程多个子工程 因为子工程依赖父工程,直接对其某个子工程进行maven clean后maven install,,,install失败 提示在本地仓库中,找不到父工程的.jar这个包...... 但是当自己去本地仓库找的时候,发现有这个父工程.jar 原来在对maven 聚合工程的单独子工程打包前,,先对父工程 进行maven clean 后maven install..... 大家有遇到这个坑没???? 「深度学习福利」大神带你进阶工程师,立即查看>>> maven依赖 com.github.ulisesbocchio jasypt-spring-boot-starter 1.8 配置加密参数(可以理解为加密的salt) jasypt: encryptor: password: 123456(这个可以随便设置的,每次设置时数据库的接连驱动要是明文(也就是不加密的,否则运行起来报错)) 写一个测试方法,这里直接在单元测试里面来实现给密码加密,得到字符串密码 @Autowired StringEncryptor stringEncryptor; @Test public void encryptPwd() { //调用加密方法 String result = stringEncryptor.encrypt("yourpassword"); System.out.println("=================="); System.out.println(result); //调用解密方法 String test=stringEncryptor.decrypt(result) System.out.println(test); System.out.println("=================="); } 把得到的密文写到需要使用到的地方,加密后的字符串需要放到ENC里面,格式如下: spring: datasource: url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false username: root password: ENC(4TyrSSgQd2DCHnXVwkdKMQ==) driver-class-name: com.mysql.jdbc.Driver 通过命令行运行 jasypt-1.9.2.jar 包命令来加密解密: 在jar包所在目录打开命令行,运行如下加密命令: java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="root" password=security algorithm=PBEWithMD5AndDES 这里input输入的可以对数据库的用户名进行加密也可以是数据库的密码进行加密 运行结果如下(这种加密每次得到的密文都是不一样的) 使用刚才加密出来的结果进行解密,执行如下解密命令: java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="i00VogiiZ1FpZR9McY7XNw==" password=security algorithm=PBEWithMD5AndDES 结果如下 「深度学习福利」大神带你进阶工程师,立即查看>>> yii版本2.0.15 从入口文件开始,首先 定义全局常量 注册composer自动加载器 包含Yii类文件 加载应用配置 引导启动,调用应用主体并配置来处理请求(也就是run方法) 1. 定义全局常量 例如定义是否开启 debug 模式,是调试环境还是正式环境,根据需要可定义自己的常量。 defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); 2. 注册composer自动加载器 composer自动加载:自动加载扩展类,及扩展类依赖另一个类,有自己的自动加载规则。 3. Yii类文件 注册Yii自动加载器,配置Yii核心类映射表,当用到某类的时候不需要检验该类咯,如果类映射表中有该类就直接引入了,是Yii的一种机制呐,要想预加载类可以配置自己的类别名。例如:urlManager路由解析组件、异常组件、MySQL PDO组件等等。注册依赖注入容器(DI)和服务定位容器。Yii也可以自动加载扩展类,前提是需要符合Composer自动加载规则。 4. 引入应用主体配置文件 配置文件主要配置应用主体属性 /yourpath/config/web.php 都是以数组形式定义的,在当前配置中又分子文件配置,职责划分了。例如数据配置文件、如何加载控制器、临时文件存储地址、邮箱配置文件、参数配置文件等,配置文件发挥着重要作用它会影响整个应用主体行为。 5. 引导启动,应用主体实例化并配置 主要是加载配置,创建应用主体实例,注册错误机制,路由解析到引导程序开始运行应用。处理当前行为前置行为执行当前行为在执行后置行为发送响应。入口脚本接收应用主体传来退出状态并完成请求。 参考文献 Yii2.0权威指南 Yii2.0 源代码 「深度学习福利」大神带你进阶工程师,立即查看>>> 当前一个正在运行的 Confluence 6 实例的内存使用情况 https://www.cwiki.us/display/CONF6ZH/Viewing+System+Information 「深度学习福利」大神带你进阶工程师,立即查看>>> 系统信息界面提供了有关 Confluence 的配置信息和 Confluence 部署的环境信息。 希望对你的系统信息进行查看: 在屏幕的右上角单击 控制台按钮 ,然后选择 General Configuration 链接。 在左侧的面板中选择选择 系统信息(System Information) 。 备注: 便捷的 内存图片( memory graph )能够帮助你查看 Conference 的内存使用情况。 当你在 Confluence 的时候如果出现了错误,你的系统信息能够帮助 Atlassian Support 诊断你遇到的问题。当登录进入 支持请求(support request) 或者 缺陷报告(bug report) 的时候,请尽可能多的提供你安装信息和环境。 https://www.cwiki.us/display/CONF6ZH/Viewing+System+Information 「深度学习福利」大神带你进阶工程师,立即查看>>> 公众平台服务号、订阅号、企业号的相关说明 1、订阅号:主要偏于为用户传达资讯(类似报纸杂志),认证前后都是每天只可以群发一条消息; 2、服务号:主要偏于服务交互(类似银行,114,提供服务查询),认证前后都是每个月可群发4条消息; 3、企业号:主要用于公司内部通讯使用,需要先验证身份才可以关注成功企业号。 温馨提示: 1)如果想简单的发送消息,达到宣传效果,建议可选择订阅号; 2)如果想用公众号获得更多的功能,例如开通微信支付,建议可以选择服务号; 3)如果想用来管理内部企业员工、团队,对内使用,可申请企业号; 4)订阅号可通过微信认证资质审核通过后有一次升级为服务号的入口,升级成功后类型不可再变; 5)服务号不可变更成订阅号。 图例说明: 本文转载自腾讯官方说明: 公众平台服务号、订阅号、企业号的相关说明 亲,如果您感觉本文有用,请点个赞再走吧✌(>‿◠)!! 「深度学习福利」大神带你进阶工程师,立即查看>>> 昨天遇到个读取图片问题,在 ImageIO.read读取大部分图片时候没有问题,可是遇到个别的gif读取就报错了: ArrayIndexOutOfBoundsException google一番,发现这是jdk6~8历史遗留问题。。。。。。差点翻车了 个别的gif很顽强! 附上链接: https://blog.csdn.net/clive_hua/article/details/77610591 , https://www.jianshu.com/p/18888311fc9e ------------------------------------------华丽的解决分界线------------------------------------ 成功读取了gif,嘿嘿。 附上解决代码: /** * 从博客中获取用于微信分享的图片链接:大小要求300x300 * @param htmlContent * @param id 博客ID * @return */ public static String getImageForWechatShare(String htmlContent, long id) { String originImageUrl = "https://static.oschina.net/uploads/space/2017/0606/104418_CPLl_2733728.png"; if (StringUtils.isNotBlank(htmlContent)) { Document document = Jsoup.parse(htmlContent); Elements elements = document.select("img[src~=(?i)\\.(gif|png|bmp|svg|jpe?g)]"); if (null == elements) { return originImageUrl; } if(elements.size() == 0) { return originImageUrl; } try { for(int i = 0; i < elements.size(); i++) { String imageUrl = elements.get(i).attr("src"); if(GIF.equalsIgnoreCase(ImageUtils.getSuffix(imageUrl))){ return readGif(originImageUrl,imageUrl,id); } HttpClient httpClient = HttpClients.createDefault(); RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(1000).setConnectionRequestTimeout(1000).setSocketTimeout(1000).build(); HttpGet httpGet = new HttpGet(imageUrl); httpGet.setConfig(requestConfig); HttpResponse response = httpClient.execute(httpGet); BufferedImage image = ImageIO.read(response.getEntity().getContent()); if (image.getWidth() > 300 && image.getHeight() > 300) { CacheMgr.set(Blog.CACHE_BLOGS_FIRST_IMAGE,String.valueOf(id),imageUrl); return imageUrl; }else{ return uploadToUp(originImageUrl,imageUrl,id); } } } catch (Exception e) { return originImageUrl; } } return originImageUrl; } /** * 读取gif * * @param originImageUrl osc 300*300 LOGO * @param imageUrl 博客第一张图片 * @param id 博客ID * @return */ public static String readGif(String originImageUrl,String imageUrl,long id) { GifDecoder.GifImage gif = null; try { gif = GifDecoder.read(getImageFromNetByUrl(imageUrl)); System.out.println(String.format("gif url:%s,width:%d,height:%d",imageUrl,gif.getWidth(),gif.getHeight())); } catch (IOException e) { return originImageUrl; } if (gif.getWidth() > 300 && gif.getHeight() > 300) { CacheMgr.set(Blog.CACHE_BLOGS_FIRST_IMAGE,String.valueOf(id),imageUrl); return imageUrl; }else{ return uploadToUp(originImageUrl,imageUrl,id); } } /** * 上传图片至又拍云 * * @param originImageUrl osc 300*300 LOGO * @param imageUrl 博客第一张图片 * @param id 博客ID * @return */ public static String uploadToUp(String originImageUrl,String imageUrl,long id){ try { imageUrl = ImageUtils.ME.upload("wx-share-blog.jpg", getImageFromNetByUrl(imageUrl)); } catch (Exception e) { return originImageUrl; } imageUrl += "!/both/300x300"; CacheMgr.set(Blog.CACHE_BLOGS_FIRST_IMAGE,String.valueOf(id),imageUrl); return imageUrl; } /** * 根据地址获得数据的字节流 * @param strUrl 网络连接地址 * @return */ public static byte[] getImageFromNetByUrl(String strUrl){ try { URL url = new URL(strUrl); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5 * 1000); InputStream inStream = conn.getInputStream(); byte[] btImg = readInputStream(inStream); return btImg; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 从输入流中获取数据 * @param inStream 输入流 * @return * @throws Exception */ public static byte[] readInputStream(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while( (len=inStream.read(buffer)) != -1 ){ outStream.write(buffer, 0, len); } inStream.close(); return outStream.toByteArray(); } 获取图片后缀: public static String getSuffix(String name) { Pattern pat = Pattern.compile("[\\w]+[\\.](" + SUFFIXES + ")");// 正则判断 Matcher mc = pat.matcher(name.toLowerCase());// 条件匹配 String fileName = null; while (mc.find()) { fileName = mc.group();// 截取文件名后缀名 } if (fileName != null) { return fileName.substring(fileName.lastIndexOf(".") + 1); } return null; } GifDecoder.java代码: import static java.lang.System.arraycopy; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /* * Copyright 2014 Dhyan Blum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * * A decoder capable of processing a GIF data stream to render the graphics * contained in it. This implementation follows the official * GIF * specification. * * * * Example usage: * * * * * * final GifImage gifImage = GifDecoder.read(int[] data); * final int width = gifImage.getWidth(); * final int height = gifImage.getHeight(); * final int frameCount = gifImage.getFrameCount(); * for (int i = 0; i < frameCount; i++) { * final BufferedImage image = gifImage.getFrame(i); * final int delay = gif.getDelay(i); * } * * * * * @author Dhyan Blum * @version 1.09 November 2017 * */ public final class GifDecoder { static final class BitReader { private int bitPos; // Next bit to read private int numBits; // Number of bits to read private int bitMask; // Use to kill unwanted higher bits private byte[] in; // Data array // To avoid costly bounds checks, 'in' needs 2 more 0-bytes at the end private final void init(final byte[] in) { this.in = in; bitPos = 0; } private final int read() { // Byte indices: (bitPos / 8), (bitPos / 8) + 1, (bitPos / 8) + 2 int i = bitPos >>> 3; // Byte = bit / 8 // Bits we'll shift to the right, AND 7 is the same as MODULO 8 final int rBits = bitPos & 7; // Byte 0 to 2, AND to get their unsigned values final int b0 = in[i++] & 0xFF, b1 = in[i++] & 0xFF, b2 = in[i] & 0xFF; // Glue the bytes together, don't do more shifting than necessary final int buf = ((b2 << 8 | b1) << 8 | b0) >>> rBits; bitPos += numBits; return buf & bitMask; // Kill the unwanted higher bits } private final void setNumBits(final int numBits) { this.numBits = numBits; bitMask = (1 << numBits) - 1; } } static final class CodeTable { private final int[][] tbl; // Maps codes to lists of colors private int initTableSize; // Number of colors +2 for CLEAR + EOI private int initCodeSize; // Initial code size private int initCodeLimit; // First code limit private int codeSize; // Current code size, maximum is 12 bits private int nextCode; // Next available code for a new entry private int nextCodeLimit; // Increase codeSize when nextCode == limit private BitReader br; // Notify when code sizes increases public CodeTable() { tbl = new int[4096][1]; } private final int add(final int[] indices) { if (nextCode < 4096) { if (nextCode == nextCodeLimit && codeSize < 12) { codeSize++; // Max code size is 12 br.setNumBits(codeSize); nextCodeLimit = (1 << codeSize) - 1; // 2^codeSize - 1 } tbl[nextCode++] = indices; } return codeSize; } private final int clear() { codeSize = initCodeSize; br.setNumBits(codeSize); nextCodeLimit = initCodeLimit; nextCode = initTableSize; // Don't recreate table, reset pointer return codeSize; } private final void init(final GifFrame fr, final int[] activeColTbl, final BitReader br) { this.br = br; final int numColors = activeColTbl.length; initCodeSize = fr.firstCodeSize; initCodeLimit = (1 << initCodeSize) - 1; // 2^initCodeSize - 1 initTableSize = fr.endOfInfoCode + 1; nextCode = initTableSize; for (int c = numColors - 1; c >= 0; c--) { tbl[c][0] = activeColTbl[c]; // Translated color } // A gap may follow with no colors assigned if numCols < CLEAR tbl[fr.clearCode] = new int[] { fr.clearCode }; // CLEAR tbl[fr.endOfInfoCode] = new int[] { fr.endOfInfoCode }; // EOI // Locate transparent color in code table and set to 0 if (fr.transpColFlag && fr.transpColIndex < numColors) { tbl[fr.transpColIndex][0] = 0; } } } final class GifFrame { // Graphic control extension (optional) // Disposal: 0=NO_ACTION, 1=NO_DISPOSAL, 2=RESTORE_BG, 3=RESTORE_PREV private int disposalMethod; // 0-3 as above, 4-7 undefined private boolean transpColFlag; // 1 Bit private int delay; // Unsigned, LSByte first, n * 1/100 * s private int transpColIndex; // 1 Byte // Image descriptor private int x; // Position on the canvas from the left private int y; // Position on the canvas from the top private int w; // May be smaller than the base image private int h; // May be smaller than the base image private int wh; // width * height private boolean hasLocColTbl; // Has local color table? 1 Bit private boolean interlaceFlag; // Is an interlace image? 1 Bit @SuppressWarnings("unused") private boolean sortFlag; // True if local colors are sorted, 1 Bit private int sizeOfLocColTbl; // Size of the local color table, 3 Bits private int[] localColTbl; // Local color table (optional) // Image data private int firstCodeSize; // LZW minimum code size + 1 for CLEAR & EOI private int clearCode; private int endOfInfoCode; private byte[] data; // Holds LZW encoded data private BufferedImage img; // Full drawn image, not just the frame area } public final class GifImage { public String header; // Bytes 0-5, GIF87a or GIF89a private int w; // Unsigned 16 Bit, least significant byte first private int h; // Unsigned 16 Bit, least significant byte first private int wh; // Image width * image height public boolean hasGlobColTbl; // 1 Bit public int colorResolution; // 3 Bits public boolean sortFlag; // True if global colors are sorted, 1 Bit public int sizeOfGlobColTbl; // 2^(val(3 Bits) + 1), see spec public int bgColIndex; // Background color index, 1 Byte public int pxAspectRatio; // Pixel aspect ratio, 1 Byte public int[] globalColTbl; // Global color table private final List frames = new ArrayList(64); public String appId = ""; // 8 Bytes at in[i+3], usually "NETSCAPE" public String appAuthCode = ""; // 3 Bytes at in[i+11], usually "2.0" public int repetitions = 0; // 0: infinite loop, N: number of loops private BufferedImage img = null; // Currently drawn frame private int[] prevPx = null; // Previous frame's pixels private final BitReader bits = new BitReader(); private final CodeTable codes = new CodeTable(); private Graphics2D g; private final int[] decode(final GifFrame fr, final int[] activeColTbl) { codes.init(fr, activeColTbl, bits); bits.init(fr.data); // Incoming codes final int clearCode = fr.clearCode, endCode = fr.endOfInfoCode; final int[] out = new int[wh]; // Target image pixel array final int[][] tbl = codes.tbl; // Code table int outPos = 0; // Next pixel position in the output image array codes.clear(); // Init code table bits.read(); // Skip leading clear code int code = bits.read(); // Read first code int[] pixels = tbl[code]; // Output pixel for first code arraycopy(pixels, 0, out, outPos, pixels.length); outPos += pixels.length; try { while (true) { final int prevCode = code; code = bits.read(); // Get next code in stream if (code == clearCode) { // After a CLEAR table, there is codes.clear(); // no previous code, we need to read code = bits.read(); // a new one pixels = tbl[code]; // Output pixels arraycopy(pixels, 0, out, outPos, pixels.length); outPos += pixels.length; continue; // Back to the loop with a valid previous code } else if (code == endCode) { break; } final int[] prevVals = tbl[prevCode]; final int[] prevValsAndK = new int[prevVals.length + 1]; arraycopy(prevVals, 0, prevValsAndK, 0, prevVals.length); if (code < codes.nextCode) { // Code table contains code pixels = tbl[code]; // Output pixels arraycopy(pixels, 0, out, outPos, pixels.length); outPos += pixels.length; prevValsAndK[prevVals.length] = tbl[code][0]; // K } else { prevValsAndK[prevVals.length] = prevVals[0]; // K arraycopy(prevValsAndK, 0, out, outPos, prevValsAndK.length); outPos += prevValsAndK.length; } codes.add(prevValsAndK); // Previous indices + K } } catch (final ArrayIndexOutOfBoundsException e) { } return out; } private final int[] deinterlace(final int[] src, final GifFrame fr) { final int w = fr.w, h = fr.h, wh = fr.wh; final int[] dest = new int[src.length]; // Interlaced images are organized in 4 sets of pixel lines final int set2Y = (h + 7) >>> 3; // Line no. = ceil(h/8.0) final int set3Y = set2Y + ((h + 3) >>> 3); // ceil(h-4/8.0) final int set4Y = set3Y + ((h + 1) >>> 2); // ceil(h-2/4.0) // Sets' start indices in source array final int set2 = w * set2Y, set3 = w * set3Y, set4 = w * set4Y; // Line skips in destination array final int w2 = w << 1, w4 = w2 << 1, w8 = w4 << 1; // Group 1 contains every 8th line starting from 0 int from = 0, to = 0; for (; from < set2; from += w, to += w8) { arraycopy(src, from, dest, to, w); } // Group 2 contains every 8th line starting from 4 for (to = w4; from < set3; from += w, to += w8) { arraycopy(src, from, dest, to, w); } // Group 3 contains every 4th line starting from 2 for (to = w2; from < set4; from += w, to += w4) { arraycopy(src, from, dest, to, w); } // Group 4 contains every 2nd line starting from 1 (biggest group) for (to = w; from < wh; from += w, to += w2) { arraycopy(src, from, dest, to, w); } return dest; // All pixel lines have now been rearranged } private final void drawFrame(final GifFrame fr) { // Determine the color table that will be active for this frame final int[] activeColTbl = fr.hasLocColTbl ? fr.localColTbl : globalColTbl; // Get pixels from data stream int[] pixels = decode(fr, activeColTbl); if (fr.interlaceFlag) { pixels = deinterlace(pixels, fr); // Rearrange pixel lines } // Create image of type 2=ARGB for frame area final BufferedImage frame = new BufferedImage(fr.w, fr.h, 2); arraycopy(pixels, 0, ((DataBufferInt) frame.getRaster().getDataBuffer()).getData(), 0, fr.wh); // Draw frame area on top of working image g.drawImage(frame, fr.x, fr.y, null); // Visualize frame boundaries during testing // if (DEBUG_MODE) { // if (prev != null) { // g.setColor(Color.RED); // Previous frame color // g.drawRect(prev.x, prev.y, prev.w - 1, prev.h - 1); // } // g.setColor(Color.GREEN); // New frame color // g.drawRect(fr.x, fr.y, fr.w - 1, fr.h - 1); // } // Keep one copy as "previous frame" in case we need to restore it prevPx = new int[wh]; arraycopy(((DataBufferInt) img.getRaster().getDataBuffer()).getData(), 0, prevPx, 0, wh); // Create another copy for the end user to not expose internal state fr.img = new BufferedImage(w, h, 2); // 2 = ARGB arraycopy(prevPx, 0, ((DataBufferInt) fr.img.getRaster().getDataBuffer()).getData(), 0, wh); // Handle disposal of current frame if (fr.disposalMethod == 2) { // Restore to background color (clear frame area only) g.clearRect(fr.x, fr.y, fr.w, fr.h); } else if (fr.disposalMethod == 3 && prevPx != null) { // Restore previous frame arraycopy(prevPx, 0, ((DataBufferInt) img.getRaster().getDataBuffer()).getData(), 0, wh); } } /** * Returns the background color of the first frame in this GIF image. If * the frame has a local color table, the returned color will be from * that table. If not, the color will be from the global color table. * Returns 0 if there is neither a local nor a global color table. * * @param index * Index of the current frame, 0 to N-1 * @return 32 bit ARGB color in the form 0xAARRGGBB */ public final int getBackgroundColor() { final GifFrame frame = frames.get(0); if (frame.hasLocColTbl) { return frame.localColTbl[bgColIndex]; } else if (hasGlobColTbl) { return globalColTbl[bgColIndex]; } return 0; } /** * If not 0, the delay specifies how many hundredths (1/100) of a second * to wait before displaying the frame after the current frame. * * @param index * Index of the current frame, 0 to N-1 * @return Delay as number of hundredths (1/100) of a second */ public final int getDelay(final int index) { return frames.get(index).delay; } /** * @param index * Index of the frame to return as image, starting from 0. * For incremental calls such as [0, 1, 2, ...] the method's * run time is O(1) as only one frame is drawn per call. For * random access calls such as [7, 12, ...] the run time is * O(N+1) with N being the number of previous frames that * need to be drawn before N+1 can be drawn on top. Once a * frame has been drawn it is being cached and the run time * is more or less O(0) to retrieve it from the list. * @return A BufferedImage for the specified frame. */ public final BufferedImage getFrame(final int index) { if (img == null) { // Init img = new BufferedImage(w, h, 2); // 2 = ARGB g = img.createGraphics(); g.setBackground(new Color(0, true)); // Transparent color } GifFrame fr = frames.get(index); if (fr.img == null) { // Draw all frames until and including the requested frame for (int i = 0; i <= index; i++) { fr = frames.get(i); if (fr.img == null) { drawFrame(fr); } } } return fr.img; } /** * @return The number of frames contained in this GIF image */ public final int getFrameCount() { return frames.size(); } /** * @return The height of the GIF image */ public final int getHeight() { return h; } /** * @return The width of the GIF image */ public final int getWidth() { return w; } } static final boolean DEBUG_MODE = false; /** * @param in * Raw image data as a byte[] array * @return A GifImage object exposing the properties of the GIF image. * @throws IOException * If the image violates the GIF specification or is truncated. */ public static final GifImage read(final byte[] in) throws IOException { final GifDecoder decoder = new GifDecoder(); final GifImage img = decoder.new GifImage(); GifFrame frame = null; // Currently open frame int pos = readHeader(in, img); // Read header, get next byte position pos = readLogicalScreenDescriptor(img, in, pos); if (img.hasGlobColTbl) { img.globalColTbl = new int[img.sizeOfGlobColTbl]; pos = readColTbl(in, img.globalColTbl, pos); } while (pos < in.length) { final int block = in[pos] & 0xFF; switch (block) { case 0x21: // Extension introducer if (pos + 1 >= in.length) { throw new IOException("Unexpected end of file."); } switch (in[pos + 1] & 0xFF) { case 0xFE: // Comment extension pos = readTextExtension(in, pos); break; case 0xFF: // Application extension pos = readAppExt(img, in, pos); break; case 0x01: // Plain text extension frame = null; // End of current frame pos = readTextExtension(in, pos); break; case 0xF9: // Graphic control extension if (frame == null) { frame = decoder.new GifFrame(); img.frames.add(frame); } pos = readGraphicControlExt(frame, in, pos); break; default: throw new IOException("Unknown extension at " + pos); } break; case 0x2C: // Image descriptor if (frame == null) { frame = decoder.new GifFrame(); img.frames.add(frame); } pos = readImgDescr(frame, in, pos); if (frame.hasLocColTbl) { frame.localColTbl = new int[frame.sizeOfLocColTbl]; pos = readColTbl(in, frame.localColTbl, pos); } pos = readImgData(frame, in, pos); frame = null; // End of current frame break; case 0x3B: // GIF Trailer return img; // Found trailer, finished reading. default: // Unknown block. The image is corrupted. Strategies: a) Skip // and wait for a valid block. Experience: It'll get worse. b) // Throw exception. c) Return gracefully if we are almost done // processing. The frames we have so far should be error-free. final double progress = 1.0 * pos / in.length; if (progress < 0.9) { throw new IOException("Unknown block at: " + pos); } pos = in.length; // Exit loop } } return img; } /** * @param is * Image data as input stream. This method will read from the * input stream's current position. It will not reset the * position before reading and won't reset or close the stream * afterwards. Call these methods before and after calling this * method as needed. * @return A GifImage object exposing the properties of the GIF image. * @throws IOException * If an I/O error occurs, the image violates the GIF * specification or the GIF is truncated. */ public static final GifImage read(final InputStream is) throws IOException { final byte[] data = new byte[is.available()]; is.read(data, 0, data.length); return read(data); } /** * @param ext * Empty application extension object * @param in * Raw data * @param i * Index of the first byte of the application extension * @return Index of the first byte after this extension */ static final int readAppExt(final GifImage img, final byte[] in, int i) { img.appId = new String(in, i + 3, 8); // should be "NETSCAPE" img.appAuthCode = new String(in, i + 11, 3); // should be "2.0" i += 14; // Go to sub-block size, it's value should be 3 final int subBlockSize = in[i] & 0xFF; // The only app extension widely used is NETSCAPE, it's got 3 data bytes if (subBlockSize == 3) { // in[i+1] should have value 01, in[i+5] should be block terminator img.repetitions = in[i + 2] & 0xFF | in[i + 3] & 0xFF << 8; // Short return i + 5; } // Skip unknown application extensions while ((in[i] & 0xFF) != 0) { // While sub-block size != 0 i += (in[i] & 0xFF) + 1; // Skip to next sub-block } return i + 1; } /** * @param in * Raw data * @param colors * Pre-initialized target array to store ARGB colors * @param i * Index of the color table's first byte * @return Index of the first byte after the color table */ static final int readColTbl(final byte[] in, final int[] colors, int i) { final int numColors = colors.length; for (int c = 0; c < numColors; c++) { final int a = 0xFF; // Alpha 255 (opaque) final int r = in[i++] & 0xFF; // 1st byte is red final int g = in[i++] & 0xFF; // 2nd byte is green final int b = in[i++] & 0xFF; // 3rd byte is blue colors[c] = ((a << 8 | r) << 8 | g) << 8 | b; } return i; } /** * @param ext * Graphic control extension object * @param in * Raw data * @param i * Index of the extension introducer * @return Index of the first byte after this block */ static final int readGraphicControlExt(final GifFrame fr, final byte[] in, final int i) { fr.disposalMethod = (in[i + 3] & 0b00011100) >>> 2; // Bits 4-2 fr.transpColFlag = (in[i + 3] & 1) == 1; // Bit 0 fr.delay = in[i + 4] & 0xFF | (in[i + 5] & 0xFF) << 8; // 16 bit LSB fr.transpColIndex = in[i + 6] & 0xFF; // Byte 6 return i + 8; // Skipped byte 7 (blockTerminator), as it's always 0x00 } /** * @param in * Raw data * @param img * The GifImage object that is currently read * @return Index of the first byte after this block * @throws IOException * If the GIF header/trailer is missing, incomplete or unknown */ static final int readHeader(final byte[] in, final GifImage img) throws IOException { if (in.length < 6) { // Check first 6 bytes throw new IOException("Image is truncated."); } img.header = new String(in, 0, 6); if (!img.header.equals("GIF87a") && !img.header.equals("GIF89a")) { throw new IOException("Invalid GIF header."); } return 6; } /** * @param fr * The GIF frame to whom this image descriptor belongs * @param in * Raw data * @param i * Index of the first byte of this block, i.e. the minCodeSize * @return */ static final int readImgData(final GifFrame fr, final byte[] in, int i) { final int fileSize = in.length; final int minCodeSize = in[i++] & 0xFF; // Read code size, go to block final int clearCode = 1 << minCodeSize; // CLEAR = 2^minCodeSize fr.firstCodeSize = minCodeSize + 1; // Add 1 bit for CLEAR and EOI fr.clearCode = clearCode; fr.endOfInfoCode = clearCode + 1; final int imgDataSize = readImgDataSize(in, i); final byte[] imgData = new byte[imgDataSize + 2]; int imgDataPos = 0; int subBlockSize = in[i] & 0xFF; while (subBlockSize > 0) { // While block has data try { // Next line may throw exception if sub-block size is fake final int nextSubBlockSizePos = i + subBlockSize + 1; final int nextSubBlockSize = in[nextSubBlockSizePos] & 0xFF; arraycopy(in, i + 1, imgData, imgDataPos, subBlockSize); imgDataPos += subBlockSize; // Move output data position i = nextSubBlockSizePos; // Move to next sub-block size subBlockSize = nextSubBlockSize; } catch (final Exception e) { // Sub-block exceeds file end, only use remaining bytes subBlockSize = fileSize - i - 1; // Remaining bytes arraycopy(in, i + 1, imgData, imgDataPos, subBlockSize); imgDataPos += subBlockSize; // Move output data position i += subBlockSize + 1; // Move to next sub-block size break; } } fr.data = imgData; // Holds LZW encoded data i++; // Skip last sub-block size, should be 0 return i; } static final int readImgDataSize(final byte[] in, int i) { final int fileSize = in.length; int imgDataPos = 0; int subBlockSize = in[i] & 0xFF; while (subBlockSize > 0) { // While block has data try { // Next line may throw exception if sub-block size is fake final int nextSubBlockSizePos = i + subBlockSize + 1; final int nextSubBlockSize = in[nextSubBlockSizePos] & 0xFF; imgDataPos += subBlockSize; // Move output data position i = nextSubBlockSizePos; // Move to next sub-block size subBlockSize = nextSubBlockSize; } catch (final Exception e) { // Sub-block exceeds file end, only use remaining bytes subBlockSize = fileSize - i - 1; // Remaining bytes imgDataPos += subBlockSize; // Move output data position break; } } return imgDataPos; } /** * @param fr * The GIF frame to whom this image descriptor belongs * @param in * Raw data * @param i * Index of the image separator, i.e. the first block byte * @return Index of the first byte after this block */ static final int readImgDescr(final GifFrame fr, final byte[] in, int i) { fr.x = in[++i] & 0xFF | (in[++i] & 0xFF) << 8; // Byte 1-2: left fr.y = in[++i] & 0xFF | (in[++i] & 0xFF) << 8; // Byte 3-4: top fr.w = in[++i] & 0xFF | (in[++i] & 0xFF) << 8; // Byte 5-6: width fr.h = in[++i] & 0xFF | (in[++i] & 0xFF) << 8; // Byte 7-8: height fr.wh = fr.w * fr.h; final byte b = in[++i]; // Byte 9 is a packed byte fr.hasLocColTbl = (b & 0b10000000) >>> 7 == 1; // Bit 7 fr.interlaceFlag = (b & 0b01000000) >>> 6 == 1; // Bit 6 fr.sortFlag = (b & 0b00100000) >>> 5 == 1; // Bit 5 final int colTblSizePower = (b & 7) + 1; // Bits 2-0 fr.sizeOfLocColTbl = 1 << colTblSizePower; // 2^(N+1), As per the spec return ++i; } /** * @param img * @param i * Start index of this block. * @return Index of the first byte after this block. */ static final int readLogicalScreenDescriptor(final GifImage img, final byte[] in, final int i) { img.w = in[i] & 0xFF | (in[i + 1] & 0xFF) << 8; // 16 bit, LSB 1st img.h = in[i + 2] & 0xFF | (in[i + 3] & 0xFF) << 8; // 16 bit img.wh = img.w * img.h; final byte b = in[i + 4]; // Byte 4 is a packed byte img.hasGlobColTbl = (b & 0b10000000) >>> 7 == 1; // Bit 7 final int colResPower = ((b & 0b01110000) >>> 4) + 1; // Bits 6-4 img.colorResolution = 1 << colResPower; // 2^(N+1), As per the spec img.sortFlag = (b & 0b00001000) >>> 3 == 1; // Bit 3 final int globColTblSizePower = (b & 7) + 1; // Bits 0-2 img.sizeOfGlobColTbl = 1 << globColTblSizePower; // 2^(N+1), see spec img.bgColIndex = in[i + 5] & 0xFF; // 1 Byte img.pxAspectRatio = in[i + 6] & 0xFF; // 1 Byte return i + 7; } /** * @param in * Raw data * @param pos * Index of the extension introducer * @return Index of the first byte after this block */ static final int readTextExtension(final byte[] in, final int pos) { int i = pos + 2; // Skip extension introducer and label int subBlockSize = in[i++] & 0xFF; while (subBlockSize != 0 && i < in.length) { i += subBlockSize; subBlockSize = in[i++] & 0xFF; } return i; } } -----ps:微信分享博客,需要300*300以上的图片。。。闹心 「深度学习福利」大神带你进阶工程师,立即查看>>> 码云、GitHub上有个很方便的功能叫fork,将别人的工程一键复制到自己账号下。这个功能很方便,但有点不足的是,当源项目更新后,你fork的分支并不会一起更新,需要自己手动去更新(并且因为要保留自己修改后的代码,更不可使用强制更新的方法)。 命令行方法 1、在本地装好Git客户端,或者GitHub客户端 2、clone 自己的fork分支到本地,可以直接使用github客户端,clone到本地,如果使用命令行,命令为: git clone git@gitee.com:Agent_ZhenyuanLiu/AllAgent.git 3、增加源分支地址到你项目远程分支列表中(此处是关键),先得将原来的仓库指定为upstream,命令为: git remote add upstream https://github.com/被fork的仓库.git 此处可使用git remote -v查看远程分支列表 4、fetch源分支的新版本到本地 [master]> git fetch upstream 5、合并两个版本的代码 [master]> git merge upstream/master 6、将合并后的代码push到github上去 [master]> git push origin master 官方解决办法: git fetch upstream # Fetches any new changes from the original repository git merge upstream/master # Merges any changes fetched into your working files GitHub站内操作 打开自己的仓库,进入code下面。 点击new pull request创建。 选择base fork 选择head fork 点击Create pull request,并填写创建信息。
6. 点击Merge pull request 合并从源fork来的代码。 7. 完成。 本文部分内容借鉴自: http://www.cnblogs.com/zyumeng/p/3442263.html https://blog.csdn.net/qq1332479771/article/details/56087333 https://help.github.com/articles/fork-a-repo http://www.shizuwu.cn/post/669.html http://segmentfault.com/q/1010000000095921 http://my.oschina.net/luffyke/blog/70336 亲,如果您感觉本文有用,请点个赞再走吧✌(>‿◠)!! 「深度学习福利」大神带你进阶工程师,立即查看>>> temp 目录是由 Java 运行时进行配置的,同时一些 Confluence 的组件将会写入历史文件或者锁定文件到这个目录中。 临时目录位于安装目录下的 /temp 目录中。 希望修改这个目录的位置,重启你的 Java虚拟机(Java Virtual Machine)的时候配置下面的参数: - Djava.io .tmpdir=/path/to/your/own/temp/directory . 请注意:这个临时目录与 Confluence Home 目录中导出的临时目录是不相同的。请查看上面表格中有关 /temp 的配置来修改你临时目录的配置。 https://www.cwiki.us/display/CONF6ZH/Confluence+Home+and+other+important+directories 「深度学习福利」大神带你进阶工程师,立即查看>>> 介绍 IP是TCP/IP协议栈中最核心的协议,TCP、UDP、ICMP和IGMP都基于IP协议传输数据 IP协议的两个重要特点: 不可靠:不保证IP数据报成功传输到目的地,可靠性由上层保障 无连接:不维护数据报的状态信息。每个数据报都是独立传输,可能A在B之前传输,但是A在B之后到达 IP首部 其中普通IP首部占据20字节,除非包含可选字段,并且IP数据报的长度一定是32位的整数倍 版本号:4位。IPv4的版本号是4 首部长度:4位。代表图中首部占据了多少个32位。4位首部长度说明首部最长为 2^4-1=15 个32位,即60字节 服务类型(TOS):8位。其中3位优先权子字段(已忽略)、4位TOS子字段和1位未用位。4位TOS最多设置其中一个位,如果全0代表一般服务,这4位分别是:最小时延、最大吞吐量、最高可靠性、最小费用。根据不同类型,来选择不同的执行逻辑 总长度:16位。整个IP数据报的总长度,通过首部长度和总长度,可以知道数据内容的起始位置和长度 标识:16位。唯一标识主机发送的数据报,每发送一份报文都会加1 标志:3位。 偏移:13位。 生存时间:8位。数据报最多经过的路由器数 协议:8位。表明是哪个上层协议向IP发送数据,根据这个字段在收到数据报的时候可用正确分用 首部校验和:16位。根据IP首部计算的校验和 选项(如果有):不定长。如有需求,会额外增加的字段,可选 IP路由选择 IP收到上层的数据报,搜索路由表,根据搜索结果并完成发送 IP收到下层网络接口传上来的数据报,check数据报中目的IP是否为本机。如果是,则交给IP首部字段指定的协议模块解析;如果不是,则若本机无路由功能就丢弃数据报,若本机有路由功能则进行路由表搜索和转发 路由表: 目的IP地址:可以是网络地址,也可以是主机地址 下一站路由器的IP地址:直连网络的路由器IP,通过该路由器将数据转发到目的地 标志:一个标志区分目的IP是网络地址还是主机地址;另一个标志区分下一站路由器是真正的路由器还是直连的网络接口 为数据报传输指定一个网络接口 IP路由是逐跳地(hop-by-hop)进行,IP并不知道到达目的地的完整路径,只是通过路由寻找到下一站路由器,如此不断接近终点 IP路由选择过程: 搜索路由表,找到与目标IP完全匹配的条目,将报文发送给该条目的下一站路由器或直连的网络接口 搜索路由表,找到与目标网络号匹配的条目,将报文发送给该条目的下一站路由器或直连的网络接口 搜索路由表,找到“默认”条目,将报文发送给该条目的下一站路由器或直连的网络接口 为每个网络指定一个路由器,可以减少路由表的规模 大部分主机和路由器可以采用“默认”路由条目将数据传送到目的地 逐跳传递过程中,目的IP地址不变化 逐跳传递过程中,链路层数据帧首部的目的地址始终指向下一站链路层的目的地址(mac地址) 子网寻址 子网的目的: 如果网络下直接就是主机号,通常一个网络可用主机号较多,实际用不了这么多,浪费 子网对外只需要暴露网关的IP地址,可用极大减少Internet路由表规模 通常B类地址才划分子网 子网掩码 用来确定IP地址中有多少位是网络号和子网号,有多少位是主机号 有盘主机通常在系统启动的时候,会读取磁盘中的文件来获取IP地址和子网掩码 通过子网掩码可以确定目标地址与本机地址是否在: 其他网络 同一个网络 同一个子网 这个功能也是路由选择中不断进行的步骤 特殊的IP地址 变长子网 当一个子网(如图中子网13)中存在多个网络(如图中SLIP和以太网),就需要通过增加子网的长度,来区分该子网是SLIP子网还是以太网子网。这种改变子网长度,称为变长子网 3-10中各接口IP
「深度学习福利」大神带你进阶工程师,立即查看>>> 针对生产系统中,我们推荐你使用远程监控,这个将不会消耗你远程 Confluence 服务器的资源。 启动远程监控: 添加下面的属性到 setenv.sh / setenv.bat 文件中,端口你可以定义任何你没有使用的端口。 set CATALINA_OPTS= -Dcom.sun.management.jmxremote %CATALINA_OPTS% set CATALINA_OPTS= -Dcom.sun.management.jmxremote.port= 8099 %CATALINA_OPTS% 确定你将如何保持你远程连接的安全。请 Remote Monitoring and Management 页面来获得更多的信息。 尽管可以在监控的时候禁用安全授权,我们不推荐你在生产环境下配置使用禁用安全授权。 启动 JConsole (你可以在 JDK 安装目录中找到了启动需要的 bin)。 选择 远程进程(Remote Process) 。 输入你的主机名和端口(这个端口是你在配置文件中配置的,这个端口不是你 Confluence 运行的端口)。 单击 连接( Connect )。 请参考 Using JConsole 来获得有关远程监控的更多有用信息。 https://www.cwiki.us/display/CONF6ZH/Live+Monitoring+Using+the+JMX+Interface 「深度学习福利」大神带你进阶工程师,立即查看>>> 你可以使用下面的 Confluence MBeans 来实时查看你 Confluence 实例运行的实时信息。 CacheStatistics 这个 MBean 显示了 Confluence 有关的缓存信息。有关更多的内容请查看 Viewing System Information 页面中的内容。 IndexingStatistics 这个 MBean 显示有关搜索索引的相关信息。这里是一些有用的配置属性。 Flushing | 显示当前缓存有没有刷新。 | 布尔值(True/False) |
---|
LastElapsedMilliseconds | 上一次进行索引所消耗的时间。 | 毫秒(Milliseconds) TaskQueueLength | ReIndexing 显示任务队列中的数量。 | 确定 Confluence 当前是否在进行重新索引。 整数(Integer) | 布尔值(True/False) |
SystemInformation 这个 MBean 显示了 Confluence 的版本和已经运行的时间想信息。你也可以通过 Viewing System Information 页面来查看这方面的信息。 DatabaseExampleLatency 显示进行数据库示例查询的延迟时间。 毫秒(Milliseconds) RequestMetrics 这个 MBean 显示了系统负载和错误页面的相关信息。 AverageExecutionTimeForLastTenRequests | 最后 10 个查询执行的平均时间。 | 毫秒(Milliseconds) |
---|
CurrentNumberOfRequestsBeingServed | 这个实例已经执行的查询数量。 | 整数(Integer) ErrorCount | NumberOfRequestsInLastTenSeconds Confluence 错误页面的数量。 | 最后 10 秒内执行的查询数量 整数(Integer) | 整数(Integer) |
MailServer-SMTPServer 这个 MBean 显示了电子邮件发送和失败的相关信息。针对你安装的 Confluence 实例中的每一个系统中配置的 SMTP 邮件服务器,都会有一个独立的 MBean 显示。 EmailsAttempted EmailsSent Confluence 尝试发送的电子邮件数量。 | 成功发送的电子邮件数量。 Integer | Integer MailTaskQueue 这个 MBean 显示电子邮件有关的工作情况。
ErrorQueueSize | 队列中的错误数量。 | 整数(Integer) |
---|
Flushing | 显示状态(例如:flushing 或不是)。 | 布尔值(True/False) | FlushStarted | 操作开始的时间。 | 时间(Time) RetryCount | TaskSize 整个操作总计处理已处理的总数。 | 需要等待发送的电子邮件队列中的消息数量。 整数(Integer) | 整数(Integer) | SchedulingStatistics 这个 MBean 显示当前任务有关的信息,已经计划的任务和这些任务上次运行所花费的时间。
AllJobNames | CurrentlyRunningJobNames 显示当前任务有关的信息,已经计划的任务和这些任务上次运行所花费的时间。 | 显示当前正在执行的计划任务。 字符串(String) | 列表(List) https://www.cwiki.us/display/CONF6ZH/Live+Monitoring+Using+the+JMX+Interface 「深度学习福利」大神带你进阶工程师,立即查看>>> 其他 MBeans 希望监控 Hibernate 和 Hazelcast(仅针对 Confluence 数据中心)你需要在你的 setenv.sh / setenv.bat 文件中添加下面的内容。 set CATALINA_OPTS= -Dconfluence.hazelcast.jmx.enable= true %CATALINA_OPTS% set CATALINA_OPTS= -Dconfluence.hibernate.jmx.enable= true %CATALINA_OPTS% |
---|
这个修改将会让 Hibernate 和 Hazelcast 的 MBeans 在你的 JMX 客户端中可查看。 监控高 CPU 消耗线程 JConsole Top Threads Plugin 插件能够帮你监控当前那个线程消耗了最多的 CPU 时间,你可以在启动的时候添加下面的启动参数来启动这个插件: JConsole -pluginpath /pathto/ topthreads.jar |
---|
https://www.cwiki.us/display/CONF6ZH/Live+Monitoring+Using+the+JMX+Interface 「深度学习福利」大神带你进阶工程师,立即查看>>> 其他 MBeans 希望监控 Hibernate 和 Hazelcast(仅针对 Confluence 数据中心)你需要在你的 setenv.sh / setenv.bat 文件中添加下面的内容。 set CATALINA_OPTS= -Dconfluence.hazelcast.jmx.enable= true %CATALINA_OPTS% set CATALINA_OPTS= -Dconfluence.hibernate.jmx.enable= true %CATALINA_OPTS% |
---|
这个修改将会让 Hibernate 和 Hazelcast 的 MBeans 在你的 JMX 客户端中可查看。 监控高 CPU 消耗线程 JConsole Top Threads Plugin 插件能够帮你监控当前那个线程消耗了最多的 CPU 时间,你可以在启动的时候添加下面的启动参数来启动这个插件: JConsole -pluginpath /pathto/ topthreads.jar |
---|
https://www.cwiki.us/display/CONF6ZH/Live+Monitoring+Using+the+JMX+Interface | |
---|
|