四、Socket网络通信编程–Netty实践
1、数据通信
一般在项目中我们该如何去使用Netty呢?大体上对于一些参数配置都是根据服务器性能决定的。这个不是最主要的。
我们需要考虑的问题是两台机器(甚至多台)使用Netty怎样进行通信,一般分为三种:
- 1 第一种,使用长连接通道不断开的形式进行通信,也就是服务器和客户端一直处于开启状态,如果服务器性能足够好,并且我们的客户端数量也比较少的情况下,还是可以采用这种方式的。
- 2 第二种,一次性批量提交数据,采用短连接方式。也就是我们会把数据保存在本地临时缓冲区或者临时表里,当达到临界值时进行一次性批量提交,又或者根据定时任务轮询提交,这种情况弊端是做不到实时性传输,在对实时性不高的应用程序中可以推荐使用。
- 3 第三种,使用一种特殊的长连接,在指定某一时间内,服务器与某太客户端没有任何通信,则断开练级恩。下次连接则是客户端想服务器端发起请求的时候,再次建立连接。但是这种模式我们需要考虑2个因素:
- (1) 如何在超时(即服务器和客户端没有任何通信)后关闭通道?关闭通道后我们又如何再次建立连接? 答:可以使用连接的时候添加判断,如果连接状态是可以用的那么直接使用,否则重新建立连接。
- (2)客户端宕机时,我们无需考虑,下次客户端重启之后,我们就可以与服务器建立连接,但是服务器宕机时,我们的客户端如何与服务器进行连接呢? 答:可以在客户端使用定时任务去轮询连接,直到连接成功建立为止
(一)上述第三种方式的应用例子
Netty已经为我们提供了超时机制,只需要在配置Bootstrap中初始化ChannelInitializer时增加超时处理器ReadTimeoutHandler就可以了sChannel.pipeline().addLast(new ReadTimeoutHandler(5));
单位为秒。理论上只需要在一端增加即可,为了双重保险,建议客户端和服务器端同时配置。另外注意在数据发送完毕之后不能添加监听去关闭连接(writeFlush.addListener(ChannelFutureListener.CLOSE);
),因为该监听会立即断开连接。
Client.java连接配置
bootstrap.group(workerGroup) .channel(NioSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sChannel) throws Exception { // TODO Auto-generated method stub sChannel.pipeline().addLast(MarshallingCodeFactory.buildMarshallingEncoder()); sChannel.pipeline().addLast(MarshallingCodeFactory.buildMarshallingDecode()); //超时设置 sChannel.pipeline().addLast(new ReadTimeoutHandler(5)); sChannel.pipeline().addLast(new ClientHandler()); } }) .option(ChannelOption.SO_KEEPALIVE, true);
分离建立连接的方法
public void connect(){ try { this.channelFuture = bootstrap.connect("127.0.0.1", 8765).sync(); System.out.println("远程服务器已经连接,可以进行数据交换!"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
提供获取ChannelFuture的方法,当需要发送数据时,调用该方法获取通信管道,传输数据
public ChannelFuture getChannelFuture(){ //获取连接,如果连接未初始化过,则初始化建立连接 if( null == this.channelFuture ){ this.connect(); } //判断连接是否可用,如果不可用则重新连接 if( !this.channelFuture.channel().isActive() ){ this.connect(); } return this.channelFuture; }
测试方法
public static void main(String[] args) { Client2 client2 = Client2.getInstance(); ChannelFuture channelFuture = null; for(int i = 0; i < 4; i++){ channelFuture = client2.getChannelFuture(); Request req = new Request(); req.setId("id_" + i); req.setName("name_" + i); req.setRequestMessage("数据消息_" + i); channelFuture.channel().writeAndFlush(req); try { TimeUnit.SECONDS.sleep(6); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { //注意,此处一定要调用异步关闭channelFuture的监听方法,这样来保证管道的正常关闭,否则执行完毕之后,main函数直接执行完毕,强行关闭连接,服务器端会报:“远程主机强制关闭了一个现有连接”的异常。 channelFuture.channel().closeFuture().sync(); //阻塞通信管道,异步等待管道关闭 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("断开连接,主线程结束.."); }
Server.java配置
ServerBootstrap serverBootstrap = new ServerBootstrap(); //将连接接收组与事件处理组连接,当server的bossGroup接收到连接之后就会交给workerGroup进行处理 serverBootstrap.group(bossGroup, workerGroup) //指定接收的Channel类型 .channel(NioServerSocketChannel.class) //handler在初始化时就会执行,而childHandler会在客户端成功connect后才执行,这是两者的区别。 .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel channel) throws Exception { // TODO Auto-generated method stub channel.pipeline().addLast(MarshallingCodeFactory.buildMarshallingEncoder()); channel.pipeline().addLast(MarshallingCodeFactory.buildMarshallingDecode()); //超时设置 channel.pipeline().addLast(new ReadTimeoutHandler(5)); channel.pipeline().addLast(new ServerHandler()); } }) //设置TCP缓冲区的大小 .option(ChannelOption.SO_BACKLOG, 128) //设置是否保持连接 .childOption(ChannelOption.SO_KEEPALIVE, true);
2、心跳监控
在使用Socket时一般经常会处理多个服务器之间的心跳检测,一般来讲,我们去维护服务器集群,肯定有一台或几台服务器主机(Master),然后还应该有N台从机(Slave),那么我们的主机肯定要时时刻刻知道自己下面的从服务器的各方面情况,然后进行实时监控的功能,这个在分布式架构里叫做心跳检测或者说心跳监控。最佳处理方案我们还是决定是使用一些通信架构来进行实现。Netty就可以去做这样一件事。
MasterServer.java
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 io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; public class MasterServer { public void init(int port){ //用于接收网络连接 EventLoopGroup bossGroup = new NioEventLoopGroup(); //用于处理实际工作 EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); try { serverBootstrap.group(bossGroup, workGroup); serverBootstrap.channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sc) throws Exception { // TODO Auto-generated method stub sc.pipeline().addLast(MarshallingCodeFactory.buildMarshallingEncoder()); sc.pipeline().addLast(MarshallingCodeFactory.buildMarshallingDecode()); sc.pipeline().addLast(new MasterServerHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind(port).sync(); System.out.println("Master Server started. port : " + port); channelFuture.channel().closeFuture().sync(); bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } public static void main(String[] args) { new MasterServer().init(8765); } }
MasterServerHandler.java
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import java.util.HashMap; import java.util.Map; public class MasterServerHandler extends ChannelHandlerAdapter{ private static final String SUCCESS_KEY = "auth_success_key"; private static final String FAILURE_KEY = "auth_failure_key"; //存放从机信息的列表map private static Map<String, String> AUTH_IP_MAP = new HashMap<String, String>(); //模拟从数据库读取数据,存入map,真实环境中应该是从数据库或缓存中读取 static{ AUTH_IP_MAP.put("172.29.132.218", "1234"); } /** * 丛机slave的权限校验。此处只是简单的验证处理,真实环境中应该根据实际情况去进行加解密处理或其他更安全的方式进行验证 * @param ctx * @param msg */ private boolean auth(ChannelHandlerContext ctx, Object msg){ String[] ret = ((AuthRequest)msg).getAuth().split(":"); String auth = AUTH_IP_MAP.get(ret[0]); if( null != auth && auth.equals(ret[1]) ){ ctx.writeAndFlush(new AuthResponse(SUCCESS_KEY)); System.out.println("权限校验通过"); return true; }else{ System.out.println("权限校验失败!"); //权限校验失败应该主动断开该次连接 ctx.writeAndFlush(new AuthResponse(FAILURE_KEY)).addListener(ChannelFutureListener.CLOSE); return false; } } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // TODO Auto-generated method stub System.out.println("master read..."); System.out.println( msg instanceof AuthRequest); if( ( msg instanceof AuthRequest ) ){ this.auth(ctx, msg); }else if( ( msg instanceof HeartBeatRequest ) ){ HeartBeatRequest req = (HeartBeatRequest)msg; System.out.println("--------------------------------------------"); System.out.println("当前主机ip为: " + req.getIp()); System.out.println("当前主机cpu情况: "); Map cpu = req.getCupMap(); System.out.println("总使用率: " + cpu.get("combined")); System.out.println("用户使用率: " + cpu.get("user")); System.out.println("系统使用率: " + cpu.get("sys")); System.out.println("等待率: " + cpu.get("wait")); System.out.println("空闲率: " + cpu.get("idle")); System.out.println("当前主机memory情况: "); Map memory = req.getMemoryMap(); System.out.println("内存总量: " + memory.get("total")); System.out.println("当前内存使用量: " + memory.get("used")); System.out.println("当前内存剩余量: " + memory.get("free")); System.out.println("--------------------------------------------"); ctx.writeAndFlush(new HeartBeatResponse("info received!")); }else { ctx.writeAndFlush(new Error("connect failure!")).addListener(ChannelFutureListener.CLOSE); } } }
SlaveClient.java
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 io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; public class SlaveClient { public void init(String ip, int port) { // TODO Auto-generated method stub EventLoopGroup wGroup = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); try { bootstrap.group(wGroup) .channel(NioSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sc) throws Exception { // TODO Auto-generated method stub sc.pipeline().addLast(MarshallingCodeFactory.buildMarshallingEncoder()); sc.pipeline().addLast(MarshallingCodeFactory.buildMarshallingDecode()); sc.pipeline().addLast(new SlaveClientHeartBeatHandler()); } }); ChannelFuture channelFuture = bootstrap.connect(ip, port).sync(); System.out.println("Slave Client started. IP : " + ip + ":" + port); channelFuture.channel().closeFuture().sync(); wGroup.shutdownGracefully(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } public static void main(String[] args) { new SlaveClient().init("172.29.132.218", 8765); } }
SlaveClientHeartBeat.java
import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.util.ReferenceCountUtil; import java.net.InetAddress; import java.util.HashMap; 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.Mem; import org.hyperic.sigar.Sigar; public class SlaveClientHeartBeatHandler extends ChannelHandlerAdapter{ private ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1); private ScheduledFuture<?> heartBeat; private InetAddress address; private static final String SUCCESS_KEY = "auth_success_key"; private static final String FAILURE_KEY = "auth_failure_key"; /** * 当连接建立激活时调用 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { // TODO Auto-generated method stub System.out.println("auth start..."); address = InetAddress.getLocalHost(); String ip = address.getHostAddress(); String key = "1234"; //模拟证书与主机进行认证, 真实环境中此处应该进行加密处理 ctx.writeAndFlush(new AuthRequest(ip + ":" + key)); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { try{ if((msg instanceof AuthResponse)){ AuthResponse ret = (AuthResponse)msg; if( SUCCESS_KEY.equals(ret.getResult()) ){ //定时任务,每隔5秒钟执行一次HeartBeatTask, 延迟0秒开始 this.heartBeat = this.scheduled.scheduleWithFixedDelay(new HeartBeatTask(ctx), 0, 5, TimeUnit.SECONDS); System.out.println(ret.getResult()); }else if(FAILURE_KEY.equals(ret.getResult())){ System.out.println("权限认证失败。"); } }else if((msg instanceof HeartBeatResponse)){ HeartBeatResponse ret = (HeartBeatResponse)msg; System.out.println(ret.getMsg()); }else if((msg instanceof Error)){ Error ret = (Error)msg; System.out.println(ret.getError()); }else{ System.out.println(msg); } }catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ ReferenceCountUtil.release(msg); } } public class HeartBeatTask implements Runnable{ private final ChannelHandlerContext ctx; public HeartBeatTask(ChannelHandlerContext ctx) { // TODO Auto-generated constructor stub this.ctx = ctx; } @Override public void run() { // TODO Auto-generated method stub try { HeartBeatRequest requestInfo = new HeartBeatRequest(); requestInfo.setIp(address.getHostAddress()); //Sigar工具类,用来获取当前系统的CPU内存等等信息,下面有详细使用介绍 Sigar sigar = new Sigar(); CpuPerc cpuPerc = sigar.getCpuPerc(); Map<String, Object> cpuMap = new HashMap<String, Object>(); cpuMap.put("combined", cpuPerc.getCombined()); cpuMap.put("user", cpuPerc.getUser()); cpuMap.put("sys", cpuPerc.getSys()); cpuMap.put("wait", cpuPerc.getWait()); cpuMap.put("idle", cpuPerc.getIdle()); requestInfo.setCupMap(cpuMap); Mem memPerc = sigar.getMem(); Map<String, Object> memMap = new HashMap<String, Object>(); memMap.put("total", memPerc.getTotal() / 1024L); memMap.put("used", memPerc.getUsed() / 1024L); memMap.put("free", memPerc.getFree() / 1024L); requestInfo.setMemoryMap(memMap); ctx.writeAndFlush(requestInfo); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } }
HeartBeatRequest.java
public class HeartBeatRequest implements Serializable{ private static final long serialVersionUID = -8534201076040524323L; private String ip; private Map<String, Object> cupMap; private Map<String, Object> memoryMap; }
HeartBeatResponse.java
public class HeartBeatResponse implements Serializable{ private static final long serialVersionUID = -1575181528386552937L; private String msg; }
AuthRequest.java
public class AuthRequest implements Serializable{ private static final long serialVersionUID = 1L; private String auth; }
AuthResponse.java
public class AuthResponse implements Serializable{ private static final long serialVersionUID = 1L; private String result; }
Sigar工具类使用介绍:
Sigar工具类下载地址需要将相应系统的DLL库放入jdk或jre的bin目录下才可以正常使用
TestSigar.java
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.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 TestSigar { public static void main(String[] args) { try { property(); System.out.println("----------------------------------"); 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 = InetAddress.getLocalHost(); String ip = addr.getHostAddress(); Map map = System.getenv(); String userName = (String) map.get("USERNAME"); String computerName = (String) map.get("COMPUTERNAME"); String userDomain = (String) map.get("USERDOMAIN"); System.out.println("用户名: " + userName); System.out.println("计算机名: " + computerName); System.out.println("计算机域名: " + userDomain); System.out.println("本地ip地址: " + ip); System.out.println("本地主机名: " + addr.getHostName()); System.out.println("JVM可以使用的总内存: " + r.totalMemory()); System.out.println("JVM可以使用的剩余内存: " + r.freeMemory()); System.out.println("JVM可以使用的处理器个数: " + r.availableProcessors()); System.out.println("Java的运行环境版本: " + props.getProperty("java.version")); System.out.println("Java的运行环境供应商: " + props.getProperty("java.vendor")); System.out.println("Java供应商的URL: " + props.getProperty("java.vendor.url")); System.out.println("Java的安装路径: " + props.getProperty("java.home")); System.out.println("Java的虚拟机规范版本: " + props.getProperty("java.vm.specification.version")); System.out.println("Java的虚拟机规范供应商: " + props.getProperty("java.vm.specification.vendor")); System.out.println("Java的虚拟机规范名称: " + props.getProperty("java.vm.specification.name")); System.out.println("Java的虚拟机实现版本: " + props.getProperty("java.vm.version")); System.out.println("Java的虚拟机实现供应商: " + props.getProperty("java.vm.vendor")); System.out.println("Java的虚拟机实现名称: " + props.getProperty("java.vm.name")); System.out.println("Java运行时环境规范版本: " + props.getProperty("java.specification.version")); System.out.println("Java运行时环境规范供应商: " + props.getProperty("java.specification.vender")); System.out.println("Java运行时环境规范名称: " + props.getProperty("java.specification.name")); System.out.println("Java的类格式版本号: " + props.getProperty("java.class.version")); System.out.println("Java的类路径: " + props.getProperty("java.class.path")); System.out.println("加载库时搜索的路径列表: " + props.getProperty("java.library.path")); System.out.println("默认的临时文件路径: " + props.getProperty("java.io.tmpdir")); System.out.println("一个或多个扩展目录的路径: " + props.getProperty("java.ext.dirs")); System.out.println("操作系统的名称: " + props.getProperty("os.name")); System.out.println("操作系统的构架: " + props.getProperty("os.arch")); System.out.println("操作系统的版本: " + props.getProperty("os.version")); System.out.println("文件分隔符: " + props.getProperty("file.separator")); System.out.println("路径分隔符: " + props.getProperty("path.separator")); System.out.println("行分隔符: " + props.getProperty("line.separator")); System.out.println("用户的账户名称: " + props.getProperty("user.name")); System.out.println("用户的主目录: " + props.getProperty("user.home")); System.out.println("用户的当前工作目录: " + props.getProperty("user.dir")); } private static void memory() throws SigarException { Sigar sigar = new Sigar(); Mem mem = sigar.getMem(); System.out.println("内存总量: " + mem.getTotal() / 1024L + "K av"); System.out.println("当前内存使用量: " + mem.getUsed() / 1024L + "K used"); System.out.println("当前内存剩余量: " + mem.getFree() / 1024L + "K free"); Swap swap = sigar.getSwap(); System.out.println("交换区总量: " + swap.getTotal() / 1024L + "K av"); System.out.println("当前交换区使用量: " + swap.getUsed() / 1024L + "K used"); System.out.println("当前交换区剩余量: " + swap.getFree() / 1024L + "K free"); } private static void cpu() throws SigarException { Sigar sigar = new Sigar(); CpuInfo[] infos = sigar.getCpuInfoList(); CpuPerc[] cpuList = null; System.out.println("cpu 总量参数情况:" + sigar.getCpu()); System.out.println("cpu 总百分比情况:" + sigar.getCpuPerc()); cpuList = sigar.getCpuPercList(); for (int i = 0; i < infos.length; i++) { CpuInfo info = infos[i]; System.out.println("第" + (i + 1) + "块CPU信息"); System.out.println("CPU的总量MHz: " + info.getMhz()); System.out.println("CPU生产商: " + info.getVendor()); System.out.println("CPU类别: " + info.getModel()); System.out.println("CPU缓存数量: " + info.getCacheSize()); printCpuPerc(cpuList[i]); } } private static void printCpuPerc(CpuPerc cpu) { System.out.println("CPU用户使用率: " + CpuPerc.format(cpu.getUser())); System.out.println("CPU系统使用率: " + CpuPerc.format(cpu.getSys())); System.out.println("CPU当前等待率: " + CpuPerc.format(cpu.getWait())); System.out.println("CPU当前错误率: " + CpuPerc.format(cpu.getNice())); System.out.println("CPU当前空闲率: " + CpuPerc.format(cpu.getIdle())); System.out.println("CPU总的使用率: " + CpuPerc.format(cpu.getCombined())); } private static void os() { OperatingSystem OS = OperatingSystem.getInstance(); System.out.println("操作系统: " + OS.getArch()); System.out.println("操作系统CpuEndian(): " + OS.getCpuEndian()); System.out.println("操作系统DataModel(): " + OS.getDataModel()); System.out.println("操作系统的描述: " + OS.getDescription()); System.out.println("操作系统的卖主: " + OS.getVendor()); System.out.println("操作系统的卖主名: " + OS.getVendorCodeName()); System.out.println("操作系统名称: " + OS.getVendorName()); System.out.println("操作系统卖主类型: " + OS.getVendorVersion()); System.out.println("操作系统的版本号: " + OS.getVersion()); } private static void who() throws SigarException { Sigar sigar = new Sigar(); Who[] who = sigar.getWhoList(); if ((who != null) && (who.length > 0)) for (int i = 0; i < who.length; i++) { Who _who = who[i]; System.out.println("用户控制台: " + _who.getDevice()); System.out.println("用户host: " + _who.getHost()); System.out.println("当前系统进程表中的用户名: " + _who.getUser()); } } private static void file() throws Exception { Sigar sigar = new Sigar(); FileSystem[] fslist = sigar.getFileSystemList(); for (int i = 0; i < fslist.length; i++) { System.out.println("分区的盘符名称" + i); FileSystem fs = fslist[i]; System.out.println("盘符名称: " + fs.getDevName()); System.out.println("盘符路径: " + fs.getDirName()); System.out.println("盘符标志: " + fs.getFlags()); System.out.println("盘符类型: " + fs.getSysTypeName()); System.out.println("盘符类型名: " + fs.getTypeName()); System.out.println("盘符文件系统类型: " + fs.getType()); FileSystemUsage usage = null; usage = sigar.getFileSystemUsage(fs.getDirName()); switch (fs.getType()) { case 0: break; case 1: break; case 2: System.out.println(fs.getDevName() + "总大小: " + usage.getTotal() + "KB"); System.out.println(fs.getDevName() + "剩余大小: " + usage.getFree() + "KB"); System.out.println(fs.getDevName() + "可用大小: " + usage.getAvail() + "KB"); System.out.println(fs.getDevName() + "已经使用量: " + usage.getUsed() + "KB"); double usePercent = usage.getUsePercent() * 100.0D; System.out.println(fs.getDevName() + "资源的利用率: " + usePercent + "%"); break; case 3: break; case 4: break; case 5: break; case 6: } System.out.println(fs.getDevName() + "读出: " + usage.getDiskReads()); System.out.println(fs.getDevName() + "写入: " + usage.getDiskWrites()); } } private static void net() throws Exception { Sigar sigar = new Sigar(); String[] ifNames = sigar.getNetInterfaceList(); for (int i = 0; i < ifNames.length; i++) { String name = ifNames[i]; NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name); System.out.println("网络设备名: " + name); System.out.println("IP地址: " + ifconfig.getAddress()); System.out.println("子网掩码: " + ifconfig.getNetmask()); if ((ifconfig.getFlags() & 1L) <= 0L) { System.out.println("!IFF_UP...skipping getNetInterfaceStat"); } else { NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name); System.out.println(name + "接收的总包裹数:" + ifstat.getRxPackets()); System.out.println(name + "发送的总包裹数:" + ifstat.getTxPackets()); System.out.println(name + "接收到的总字节数:" + ifstat.getRxBytes()); System.out.println(name + "发送的总字节数:" + ifstat.getTxBytes()); System.out.println(name + "接收到的错误包数:" + ifstat.getRxErrors()); System.out.println(name + "发送数据包时的错误数:" + ifstat.getTxErrors()); System.out.println(name + "接收时丢弃的包数:" + ifstat.getRxDropped()); System.out.println(name + "发送时丢弃的包数:" + ifstat.getTxDropped()); } } } private static void ethernet() throws SigarException { Sigar sigar = null; sigar = new Sigar(); String[] ifaces = sigar.getNetInterfaceList(); for (int i = 0; i < ifaces.length; i++) { NetInterfaceConfig cfg = sigar.getNetInterfaceConfig(ifaces[i]); if (("127.0.0.1".equals(cfg.getAddress())) || ((cfg.getFlags() & 0x8) != 0L) || ("00:00:00:00:00:00".equals(cfg.getHwaddr()))) { continue; } System.out.println(cfg.getName() + "IP地址:" + cfg.getAddress()); System.out.println(cfg.getName() + "网关广播地址:" + cfg.getBroadcast()); System.out.println(cfg.getName() + "网卡MAC地址:" + cfg.getHwaddr()); System.out.println(cfg.getName() + "子网掩码:" + cfg.getNetmask()); System.out .println(cfg.getName() + "网卡描述信息:" + cfg.getDescription()); System.out.println(cfg.getName() + "网卡类型" + cfg.getType()); } } }