linux怎么查看本机内存大小
320
2022-11-30
JavaNetty心跳监听(三)
使用定时发送消息的方式,实现硬件检测,达到心态检测的目的。
心跳监测是用于检测电脑硬件和软件信息的一种技术。如:CPU 使用率,磁盘使用率, 内存使用率,进程情况,线程情况等。 4.5.1 sigar 需要下载一个 zip 压缩包。内部包含若干 sigar 需要的操作系统文件。sigar 插件是通过 JVM 访问操作系统,读取计算机硬件的一个插件库。读取计算机硬件过程中,必须由操作系统提供硬件信息。硬件信息是通过操作系统提供的。zip 压缩包中是 sigar 编写的操作系统文 件,如:windows 中的动态链接库文件。
解压需要的操作系统文件,将操作系统文件赋值到${Java_home}/bin 目录中
import java.net.InetAddress;import java.net.UnknownHostException;import java.util.Map;import java.util.Properties;import org.hyperic.sigar.CpuInfo;import org.hyperic.sigar.CpuPerc;import org.hyperic.sigar.FileSystem;import org.hyperic.sigar.FileSystemUsage;import org.hyperic.sigar.Mem;import org.hyperic.sigar.NetFlags;import org.hyperic.sigar.NetInterfaceConfig;import org.hyperic.sigar.NetInterfaceStat;import org.hyperic.sigar.OperatingSystem;import org.hyperic.sigar.Sigar;import org.hyperic.sigar.SigarException;import org.hyperic.sigar.Swap;import org.hyperic.sigar.Who;public class OSUtils { public static void main(String[] args) { try { // System信息,从jvm获取 property(); System.out.println("----------------------------------"); // cpu信息 cpu(); System.out.println("----------------------------------"); // 内存信息 memory(); System.out.println("----------------------------------"); // 操作系统信息 os(); System.out.println("----------------------------------"); // 用户信息 who(); System.out.println("----------------------------------"); // 文件系统信息 file(); System.out.println("----------------------------------"); // 网络信息 net(); System.out.println("----------------------------------"); // 以太网信息 ethernet(); System.out.println("----------------------------------"); } catch (Exception e1) { e1.printStackTrace(); } } private static void property() throws UnknownHostException { Runtime r = Runtime.getRuntime(); Properties props = System.getProperties(); InetAddress addr; addr = InetAddress.getLocalHost(); String ip = addr.getHostAddress(); Map
/** * 1. 双线程组 * 2. Bootstrap配置启动信息 * 3. 注册业务处理Handler * 4. 绑定服务监听端口并启动服务 */import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;import utils.SerializableFactory4Marshalling;public class Server4Heatbeat { // 监听线程组,监听客户端请求 private EventLoopGroup acceptorGroup = null; // 处理客户端相关操作线程组,负责处理与客户端的数据通讯 private EventLoopGroup clientGroup = null; // 服务启动相关配置信息 private ServerBootstrap bootstrap = null; public Server4Heatbeat(){ init(); } private void init(){ acceptorGroup = new NioEventLoopGroup(); clientGroup = new NioEventLoopGroup(); bootstrap = new ServerBootstrap(); // 绑定线程组 bootstrap.group(acceptorGroup, clientGroup); // 设定通讯模式为NIO bootstrap.channel(NioServerSocketChannel.class); // 设定缓冲区大小 bootstrap.option(ChannelOption.SO_BACKLOG, 1024); // SO_SNDBUF发送缓冲区,SO_RCVBUF接收缓冲区,SO_KEEPALIVE开启心跳监测(保证连接有效) bootstrap.option(ChannelOption.SO_SNDBUF, 16*1024) .option(ChannelOption.SO_RCVBUF, 16*1024) .option(ChannelOption.SO_KEEPALIVE, true); } public ChannelFuture doAccept(int port) throws InterruptedException{ bootstrap.childHandler(new ChannelInitializer
import java.util.ArrayList;import java.util.List;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;import utils.HeatbeatMessage;public class Server4HeatbeatHandler extends ChannelHandlerAdapter { private static List
/** * 1. 单线程组 * 2. Bootstrap配置启动信息 * 3. 注册业务处理Handler * 4. connect连接服务,并发起请求 */import io.netty.bootstrap.Bootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioSocketChannel;import utils.SerializableFactory4Marshalling;public class Client4Heatbeat { // 处理请求和处理服务端响应的线程组 private EventLoopGroup group = null; // 服务启动相关配置信息 private Bootstrap bootstrap = null; public Client4Heatbeat(){ init(); } private void init(){ group = new NioEventLoopGroup(); bootstrap = new Bootstrap(); // 绑定线程组 bootstrap.group(group); // 设定通讯模式为NIO bootstrap.channel(NioSocketChannel.class); } public ChannelFuture doRequest(String host,int port) throws InterruptedException{ this.bootstrap.handler(new ChannelInitializer
import java.net.InetAddress;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.ScheduledFuture;import java.util.concurrent.TimeUnit;import org.hyperic.sigar.CpuPerc;import org.hyperic.sigar.FileSystem;import org.hyperic.sigar.Mem;import org.hyperic.sigar.Sigar;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;import io.netty.util.ReferenceCountUtil;import utils.HeatbeatMessage;public class Client4HeatbeatHandler extends ChannelHandlerAdapter { //计划任务的线程池 private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); private ScheduledFuture heatbeat; private InetAddress remoteAddr; private static final String HEATBEAT_SUCCESS = "SERVER_RETURN_HEATBEAT_SUCCESS"; @Override public void channelActive(ChannelHandlerContext ctx) throws Exception{ // 获取本地INET信息 this.remoteAddr = InetAddress.getLocalHost(); // 获取本地计算机名 String computerName = System.getenv().get("COMPUTERNAME"); String credentials = this.remoteAddr.getHostAddress() + "_" + computerName; System.out.println(credentials); // 发送到服务器,作为信息比对证书 ctx.writeAndFlush(credentials); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { try{ if(msg instanceof String){ if(HEATBEAT_SUCCESS.equals(msg)){ this.heatbeat = this.executorService.scheduleWithFixedDelay(new HeatbeatTask(ctx), 0L, 2L, TimeUnit.SECONDS); System.out.println("client receive - " + msg); }else{ System.out.println("client receive - " + msg); } } }finally{ ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { System.out.println("client exceptionCaught method run..."); // cause.printStackTrace(); // 回收资源 if(this.heatbeat != null){ this.heatbeat.cancel(true); this.heatbeat = null; } ctx.close(); } class HeatbeatTask implements Runnable{ private ChannelHandlerContext ctx; public HeatbeatTask(){ } public HeatbeatTask(ChannelHandlerContext ctx){ this.ctx = ctx; } public void run(){ try { HeatbeatMessage msg = new HeatbeatMessage(); msg.setIp(remoteAddr.getHostAddress()); Sigar sigar = new Sigar(); // CPU信息 CpuPerc cpuPerc = sigar.getCpuPerc(); Map
4.6 HTTP 协议处理 使用 Netty 服务开发。实现 HTTP 协议处理逻辑
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; //public class HttpStaticFileServer { private final int port;//端口 public HttpStaticFileServer(int port) { this.port = port; } public void run() throws Exception{ EventLoopGroup bossGroup =new NioEventLoopGroup();//线程一 //这个是用于serversocketchannel的event EventLoopGroup workerGroup =new NioEventLoopGroup();//线程二//这个是用于处理accept到的channel try{ ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new HttpStaticFileServerInitializer()); b.bind(port).sync().channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8089; if (args.length > 0) { port = Integer.parseInt(args[0]); } else { port = 8089; } new HttpStaticFileServer(port).run();//启动服务 } }
import static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.static io.netty.handler.codec.java.io.File;import java.io.FileNotFoundException;import java.io.RandomAccessFile;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.GregorianCalendar;import java.util.Locale;import java.util.TimeZone;import java.util.regex.Pattern;import javax.activation.MimetypesFileTypeMap;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelProgressiveFuture;import io.netty.channel.ChannelProgressiveFutureListener;import io.netty.channel.DefaultFileRegion;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.io.netty.handler.codec.io.netty.handler.codec.io.netty.handler.codec.io.netty.handler.codec.io.netty.handler.codec.io.netty.handler.codec.io.netty.handler.codec.io.netty.handler.codec.io.netty.handler.stream.ChunkedFile;import io.netty.util.CharsetUtil; /** * A simple handler that serves incoming HTTP requests to send their respective * HTTP responses. It also implements {@code 'If-Modified-Since'} header to * take advantage of browser cache, as described in * &\"].*"); /** * 路径解码 * @param uri * @return */ private static String sanitizeUri(String uri) { // Decode the path. try { uri = URLDecoder.decode(uri, "UTF-8"); } catch (UnsupportedEncodingException e) { try { uri = URLDecoder.decode(uri, "ISO-8859-1"); } catch (UnsupportedEncodingException e1) { throw new Error(); } } if (!uri.startsWith("/")) { return null; } // Convert file separators. uri = uri.replace('/', File.separatorChar); // Simplistic dumb security check. // You will have to do something serious in the production environment. if (uri.contains(File.separator + '.') || uri.contains('.' + File.separator) || uri.startsWith(".") || uri.endsWith(".") || INSECURE_URI.matcher(uri).matches()) { return null; } // Convert to absolute path. return System.getProperty("user.dir") + File.separator + uri; } private static final Pattern ALLOWED_FILE_NAME = Pattern.compile("[A-Za-z0-9][-_A-Za-z0-9\\.]*"); private static void sendListing(ChannelHandlerContext ctx, File dir) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK); response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); StringBuilder buf = new StringBuilder(); String dirPath = dir.getPath(); buf.append("\r\n"); buf.append("Listing of: "); buf.append(dirPath); buf.append("
\r\n"); buf.append(""); buf.append("
\r\n"); ByteBuf buffer = Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8); response.content().writeBytes(buffer); buffer.release(); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } private static void sendRedirect(ChannelHandlerContext ctx, String newUri) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, FOUND); response.headers().set(LOCATION, newUri); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { FullHttpResponse response = new DefaultFullHttpResponse( HTTP_1_1, status, Unpooled.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8)); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } /** * When file timestamp is the same as what the browser is sending up, send a "304 Not Modified" * * @param ctx * Context */ private static void sendNotModified(ChannelHandlerContext ctx) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED); setDateHeader(response); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } /** * Sets the Date header for the HTTP response * * @param response * HTTP response */ private static void setDateHeader(FullHttpResponse response) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); dateFormatter.setTimeZone(TimeZone.getTimeZone(HTTP_DATE_GMT_TIMEZONE)); Calendar time = new GregorianCalendar(); response.headers().set(DATE, dateFormatter.format(time.getTime())); } /** * Sets the Date and Cache headers for the HTTP Response * * @param response * HTTP response * @param fileToCache * file to extract content type */ private static void setDateAndCacheHeaders(HttpResponse response, File fileToCache) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); dateFormatter.setTimeZone(TimeZone.getTimeZone(HTTP_DATE_GMT_TIMEZONE)); // Date header Calendar time = new GregorianCalendar(); response.headers().set(DATE, dateFormatter.format(time.getTime())); // Add cache headers time.add(Calendar.SECOND, HTTP_CACHE_SECONDS); response.headers().set(EXPIRES, dateFormatter.format(time.getTime())); response.headers().set(CACHE_CONTROL, "private, max-age=" + HTTP_CACHE_SECONDS); response.headers().set( LAST_MODIFIED, dateFormatter.format(new Date(fileToCache.lastModified()))); } /** * Sets the content type header for the HTTP Response * * @param response * HTTP response * @param file * file to extract content type */ private static void setContentTypeHeader(HttpResponse response, File file) { MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap(); response.headers().set(CONTENT_TYPE, mimeTypesMap.getContentType(file.getPath())); } }
流数据的传输处理
在基于流的传输里比如 TCP/IP,接收到的数据会先被存储到一个 socket 接收缓冲里。
不 幸的是,基于流的传输并不是一个数据包队列,而是一个字节队列。即使你发送了 2 个独立 的数据包,操作系统也不会作为 2 个消息处理而仅仅是作为一连串的字节而言。因此这是不 能保证你远程写入的数据就会准确地读取。所以一个接收方不管他是客户端还是服务端,都 应该把接收到的数据整理成一个或者多个更有意思并且能够让程序的业务逻辑更好理解的 数据。 在处理流数据粘包拆包时,可以使用下述处理方式: 使用定长数据处理,如:每个完整请求数据长度为 8 字节等。 (FixedLengthFrameDecoder) 使用特殊分隔符的方式处理,如:每个完整请求数据末尾使用’\0’作为数据结束标记。 (DelimiterBasedFrameDecoder) 使用自定义协议方式处理,如:协议格式等。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~