精华内容
下载资源
问答
  • 我不太懂java是怎么进行处理的,因为一直收数据,我处理好之后要显示在界面上,要一直更新,我是收到一帧数据处理完之后,在接收,还是具体怎么接收的,要把之后的数据一直缓存吗?我要怎么写呢?
  • 众所周知,Java语言虽然在TCP/UDP传输方面给予了良好的定义,但对于网络层以下的控制,却是无能为力的。JPCAP扩展包弥补了这一点。  JPCAP实际上并非一个真正去实现对数据链路层的控制,而是一个中间件,JPCAP调用...

    众所周知,Java语言虽然在TCP/UDP传输方面给予了良好的定义,但对于网络层以下的控制,却是无能为力的。JPCAP扩展包弥补了这一点。

         JPCAP实际上并非一个真正去实现对数据链路层的控制,而是一个中间件,JPCAP调用wincap/libpcap,而给JAVA语言提供一个公共的接口,从而实现了平台无关性。在官方网站上声明,JPCAP支持FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft windows 2000/XP等系统。

         使用Jpcap能做的事:

    1.Jpcap是直接抓取经过数据链路层的数据包。 因此可以自己写IP数据包直接发送给数据链路层。

    2.Jpcap会对抓取到的数据包进行一定程序的解析,根据数据包内容,将数据包封装为对应的对象()。

    3.根据用户设定的信息,过滤数据包(其实就是在解析的时候,对不需要的数据直接丢弃,不解析)

    4.Jpcap 只是直接从数据链路层上读取数据,并向数据链路层中发送数据,因此,Jpcap并不能操作 其他程序从数据链路层中读数据或者向网卡中发送数据。(IP层协议程序)

    二话不说首先我们先上项目结构

    所需要的jar包我已打包好

    0、客户端  InfraredSensorClient.java

    package com.airtimes.netty.network.client;
    
    
    import com.airtimes.netty.network.client.handler.InfraredSensorClientHandler;
    
    import io.netty.bootstrap.Bootstrap;
    
    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.NioSocketChannel;
    
    
    /**
     * 
     * 服务器持续监听宿主机的网卡信息、并时时返回报警中心协议在网卡中交换的数据
     * 客户端接收服务器端数据,打印出服务器送的消息
     * 
     */
    
    public class InfraredSensorClient {
    
        public static void main(String[] args)
            throws Exception {
    
            // 创建EventLoopGroup线程池 Netty内部都是通过线程在处理数据
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                // 创建客户端连接基类 用于连接服务器
                Bootstrap bootstrap = new Bootstrap(); // (1)
                // 将 EventLoopGroup 加入线程池
                bootstrap.group(workerGroup); // (2)
                // 使用changlefactory 创建通信频道
                bootstrap.channel(NioSocketChannel.class); // (3)
                // Socket网路属性
                bootstrap.option(ChannelOption.SO_KEEPALIVE, true); // (4)
                // channel处理类
                bootstrap.handler(new ChannelInitializer<SocketChannel>() {
                    // 初始化channel
                    @Override
                    public void initChannel(SocketChannel channel)
                        throws Exception {
    
                        channel.pipeline().addLast(new InfraredSensorClientHandler());
    
                    }
    
                });
    
                // Start the client.
                // 启动客户端
                ChannelFuture f = bootstrap.connect("127.0.0.1", 9090).sync(); // (5)
    
                // Wait until the connection is closed.
                // 等待连接关闭
                f.channel().closeFuture().sync();
    
            }
            finally {
                workerGroup.shutdownGracefully();
            }
    
        }
    }

                1、客户端Handler  InfraredSensorClientHandler .java

    package com.airtimes.netty.network.client.handler;
    
    
    import java.io.IOException;
    
    import com.airtimes.netty.network.response.Message;
    import com.airtimes.netty.network.tools.Util;
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import io.netty.util.ReferenceCountUtil;
    
    
    public class InfraredSensorClientHandler extends ChannelInboundHandlerAdapter {
    
        private static final Util util = new Util();
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
    
            try {
    
                ByteBuf m = (ByteBuf)msg;
                String response = util.convertByteBufToString(m);
                System.out.println("收到来自服务器json信息: " + response + "\n");
                ObjectMapper objectMapper = new ObjectMapper();
                Message ClientMessage = objectMapper.readValue(response, Message.class);
                System.out.println("收到来自服务器对象信息: " + ClientMessage.toString() + "\n");
    
            }
            catch (JsonParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (JsonMappingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            finally {
    
                ReferenceCountUtil.release(msg);
    
            }
    
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }

               2、服务器端  InfraredSensorServer  .java

    package com.airtimes.netty.network.server;
    
    
    import com.airtimes.netty.network.server.handler.InfraredSensorServerHandler;
    
    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.timeout.ReadTimeoutHandler;
    
    import io.netty.handler.timeout.WriteTimeoutHandler;
    
    
    public class InfraredSensorServer {
    
        public static void main(String[] args) {
    
            // EventLoop 代替原来的 ChannelFactory
    
            EventLoopGroup bossGroup = new NioEventLoopGroup();
    
            EventLoopGroup workerGroup = new NioEventLoopGroup();
    
            try {
    
                ServerBootstrap serverBootstrap = new ServerBootstrap();
    
                serverBootstrap.group(bossGroup, workerGroup)
    
                    .channel(NioServerSocketChannel.class)
    
                    .childHandler(new ChannelInitializer<SocketChannel>() {
    
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
    
                            ch.pipeline().addLast(
    
                                new InfraredSensorServerHandler(),
    
                                new WriteTimeoutHandler(10),
    
                                // 控制写入超时10秒构造参数10表示如果持续10秒钟都没有数据写了,那么就超时。
    
                                new ReadTimeoutHandler(10)
    
                    );
                        }
    
                    }).option(ChannelOption.SO_KEEPALIVE, true);
    
                ChannelFuture f = serverBootstrap.bind(9090).sync();
    
                f.channel().closeFuture().sync();
    
            }
            catch (InterruptedException e) {
    
            }
            finally {
    
                workerGroup.shutdownGracefully();
    
                bossGroup.shutdownGracefully();
    
            }
    
        }
    }

         3、服务器端Handler  InfraredSensorServerHandler .java

    package com.airtimes.netty.network.server.handler;
    
    
    import java.io.IOException;
    import java.util.Date;
    import java.util.UUID;
    
    import com.airtimes.netty.network.response.Message;
    import com.airtimes.netty.network.tools.TranscodingUtil;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import jpcap.JpcapCaptor;
    import jpcap.NetworkInterface;
    import jpcap.packet.EthernetPacket;
    import jpcap.packet.IPPacket;
    import jpcap.packet.Packet;
    
    
    public class InfraredSensorServerHandler extends ChannelInboundHandlerAdapter {
    
        private static final int caplen = 65535;
    
        private static final boolean promiscCheck = true;
    
        private static int f = 0;
    
        private static int i = 0;
    
        // ChannelHandlerContext通道处理上下文
        @Override
        public void channelActive(final ChannelHandlerContext ctx)
            throws InterruptedException,
            JsonProcessingException { // (1)
    
            // 第一步绑定网络设备
            NetworkInterface[] devices = JpcapCaptor.getDeviceList();
            for (NetworkInterface n : devices) {
                System.out.println("获取到本地网卡信息列表" + n.name + "     |     " + n.description);
    
            }
            System.out.println("-----------------------------------------------------------------");
    
            JpcapCaptor jpcap = null;
    
            try {
                jpcap = JpcapCaptor.openDevice(devices[2], caplen, promiscCheck, 50);
                // 指定筛选条件
                jpcap.setFilter("src 192.168.208.200 && len > 220 && len < 300 ", true);
                /* jpcap.setFilter("src 192.168.208.200 or 192.168.208.199  and len < 230 ",true); */
                // 0 或 1
            }
            catch (IOException e) {
                e.printStackTrace();
            }
    
            // 第二步抓包
            while (true) {
                Packet packet = jpcap.getPacket();
                if (packet instanceof IPPacket && ((IPPacket)packet).version == 4) {
                    
                    i++ ;
                    IPPacket ip = (IPPacket)packet;// 强转
    
                    System.out.println("-------------------------------------第" + i + "次抓取数据包参数信息--------------------------------------------");
    
                    System.out.println("版本:" + ip.version);
                    System.out.println("优先权:" + ip.priority);
                    System.out.println("区分服务:最大的吞吐量: " + ip.t_flag);
                    System.out.println("区分服务:最高的可靠性:" + ip.r_flag);
                    System.out.println("长度:" + ip.length);
                    System.out.println("标识:" + ip.ident);
                    System.out.println("DF:Don't Fragment: " + ip.dont_frag);
                    System.out.println("NF:Nore Fragment: " + ip.more_frag);
                    System.out.println("片偏移:" + ip.offset);
                    System.out.println("生存时间:" + ip.hop_limit);
    
                    String protocol = "";
                    switch (new Integer(ip.protocol)) {
                        case 1:
                            protocol = "ICMP";
                            break;
                        case 2:
                            protocol = "IGMP";
                            break;
                        case 6:
                            protocol = "TCP";
                            break;
                        case 8:
                            protocol = "EGP";
                            break;
                        case 9:
                            protocol = "IGP";
                            break;
                        case 17:
                            protocol = "UDP";
                            break;
                        case 41:
                            protocol = "IPv6";
                            break;
                        case 89:
                            protocol = "OSPF";
                            break;
                        default:
                            break;
                    }
    
                    System.out.println("协议:" + protocol);
                    System.out.println("源IP " + ip.src_ip.getHostAddress());
                    System.out.println("目的IP " + ip.dst_ip.getHostAddress());
                    /*
                     * System.out.println("源主机名: " + ip.src_ip); System.out.println("目的主机名: " + ip.dst_ip);
                     */
                    TranscodingUtil transcodingUtil = new TranscodingUtil();
                    String hexString = transcodingUtil.toHexString(ip.data);
                    String hexStringToString = transcodingUtil.hexStringToString(hexString);
    
                    String hexStringHead = transcodingUtil.toHexString(ip.header);
                    String StringHead = transcodingUtil.hexStringToString(hexStringHead);
    
                    /**********************
                     * 0-31
                     * ******************************************/
                    String substring0 = hexString.substring(0, 32);
                    System.out.println("0-31频段数据UTF_8 :" + transcodingUtil.hexStringToStringUTF(substring0));
                    System.out.println("0-31频段数据GBK   :" + transcodingUtil.hexStringToStringGBK(substring0));
                    System.out.println("0-31频段数据ISO   :" + transcodingUtil.hexStringToStringISO(substring0));
                    System.out.println("0-31频段数据GB2312:" + transcodingUtil.hexStringToString(substring0));
                    System.out.println("0-31频段数据BIG5  :" + transcodingUtil.hexStringToStringBIG(substring0));
                    System.out.println("0-31频段数据UNICOD:" + transcodingUtil.hexStringToStringUNICODE(substring0));
                    System.out.println("0-31频段数据十进制      :" + transcodingUtil.transcoding(substring0));
                    System.out.println("0-31频段数据十六进制  :" + substring0);
                    System.out.println("---------------------------------------------------------------------------------");
    
                    /**********************
                     * 32-39 错误类型
                     * B7C0 C7F8 B8D0 D3A6 C6F7 B7C0 B2F0 BBD6 B8B4 防拆恢复
                     * ******************************************/
                    String substring = hexString.substring(32, 40);
                    System.out.println("32-39频段数据UTF_8 :" + transcodingUtil.hexStringToStringUTF(substring));
                    System.out.println("32-39频段数据GBK   :" + transcodingUtil.hexStringToStringGBK(substring));
                    System.out.println("32-39频段数据ISO   :" + transcodingUtil.hexStringToStringISO(substring));
                    System.out.println("32-39频段数据GB2312:" + transcodingUtil.hexStringToString(substring));
                    System.out.println("32-39频段数据BIG5  :" + transcodingUtil.hexStringToStringBIG(substring));
                    System.out.println("32-39频段数据UNICOD:" + transcodingUtil.hexStringToStringUNICODE(substring));
                    System.out.println("32-39频段数据十进制      :" + transcodingUtil.transcoding(substring));
                    System.out.println("32-39频段数据十六进制  :" + substring);
                    System.out.println("---------------------------------------------------------------------------------");
    
                    /**********************
                     * 40-78
                     * B7C0 C7F8 B8D0 D3A6 C6F7 B7C0 B2F0 BBD6 B8B4 防拆恢复
                     * ******************************************/
                    String substring6 = hexString.substring(40, 78);
                    System.out.println("40-78频段数据UTF_8 :" + transcodingUtil.hexStringToStringUTF(substring6));
                    System.out.println("40-78频段数据GBK   :" + transcodingUtil.hexStringToStringGBK(substring6));
                    System.out.println("40-78频段数据ISO   :" + transcodingUtil.hexStringToStringISO(substring6));
                    System.out.println("40-78频段数据GB2312:" + transcodingUtil.hexStringToString(substring6));
                    System.out.println("40-78频段数据BIG5  :" + transcodingUtil.hexStringToStringBIG(substring6));
                    System.out.println("40-78频段数据UNICOD:" + transcodingUtil.hexStringToStringUNICODE(substring6));
                    System.out.println("40-78频段数据十进制      :" + transcodingUtil.transcoding(substring6));
                    System.out.println("40-78频段数据十六进制  :" + substring6);
                    System.out.println("---------------------------------------------------------------------------------");
    
                    /**********************
                     * 79-103
                     * 
                     * ******************************************/
                    String substring4 = hexString.substring(79, 103);
                    System.out.println("79-103频段数据UTF_8 :" + transcodingUtil.hexStringToStringUTF(substring4));
                    System.out.println("79-103频段数据GBK   :" + transcodingUtil.hexStringToStringGBK(substring4));
                    System.out.println("79-103频段数据ISO   :" + transcodingUtil.hexStringToStringISO(substring4));
                    System.out.println("79-103频段数据GB2312:" + transcodingUtil.hexStringToString(substring4));
                    System.out.println("79-103频段数据BIG5  :" + transcodingUtil.hexStringToStringBIG(substring4));
                    System.out.println("79-103频段数据UNICOD:" + transcodingUtil.hexStringToStringUNICODE(substring4));
                    System.out.println("79-103频段数据十进制      :" + transcodingUtil.transcoding(substring4));
                    System.out.println("79-103频段数据十六进制  :" + substring4);
                    System.out.println("---------------------------------------------------------------------------------");
    
                    /*********
                     104-119
                     * ************************************************/
                    String substring2 = hexString.substring(104, 155);
                    // 月份
                    String month = hexString.substring(108, 110);
                    String transmonth = transcodingUtil.transcoding(month);
                    // 日份
                    String day = hexString.substring(110, 112);
                    String transday = transcodingUtil.transcoding(day);
                    // 时间
                    String hour = hexString.substring(112, 114);
                    String transhour = transcodingUtil.transcoding(hour);
                    // 分钟
                    String min = hexString.substring(114, 116);
                    String transmin = transcodingUtil.transcoding(min);
    
                    // 秒
                    String sec = hexString.substring(116, 119);
                    Integer transec = null;
                    if (Integer.parseInt(transcodingUtil.transcoding(sec)) > 6) {
    
                        transec = Integer.parseInt(transcodingUtil.transcoding(sec)) - 6;
                        System.err.println("D" + transec);
                    }
                    else {
    
                        transec = Integer.parseInt(transcodingUtil.transcoding(sec));
                        System.err.println("X" + transec);
                    }
    
                    System.out.println("104-119频段数据UTF_8 :" + transcodingUtil.hexStringToStringUTF(substring2));
                    System.out.println("104-119频段数据GBK   :" + transcodingUtil.hexStringToStringGBK(substring2));
                    System.out.println("104-119频段数据ISO   :" + transcodingUtil.hexStringToStringISO(substring2));
                    System.out.println("104-119频段数据GB2312:" + transcodingUtil.hexStringToString(substring2));
                    System.out.println("104-119频段数据BIG5  :" + transcodingUtil.hexStringToStringBIG(substring2));
                    System.out.println("104-119频段数据UNICOD:" + transcodingUtil.hexStringToStringUNICODE(substring2));
                    System.out.println("104-119频段数据拼接后时间序列:" + transmonth + "-" + transday + " " + transhour + ":"
                                       + transmin + ":" + transec);
                    System.out.println("104-119频段数据十进制      :" + transcodingUtil.transcoding(substring2));
                    System.out.println("104-119频段数据—月份      :" + transmonth + "月");
                    System.out.println("104-119频段数据—日期      :" + transday + "日");
                    System.out.println("104-119频段数据—小时      :" + transhour + "时");
                    System.out.println("104-119频段数据—分钟      :" + transmin + "分钟");
                    System.out.println("104-119频段数据— 秒       :" + transec + "秒");
                    System.out.println("当前时间戳:" + System.currentTimeMillis());
                    System.out.println("104-119频段数据十六进制  :" + substring2);
                    System.out.println("---------------------------------------------------------------------------------");
    
                    /*********
                     120-197
                    * ************************************************/
    
                    String substring5 = hexString.substring(120, 197);
    
                    System.out.println("120-197频段数据UTF_8 :" + transcodingUtil.hexStringToStringUTF(substring5));
                    System.out.println("120-197频段数据GBK   :" + transcodingUtil.hexStringToStringGBK(substring5));
                    System.out.println("120-197频段数据ISO   :" + transcodingUtil.hexStringToStringISO(substring5));
                    System.out.println("120-197频段数据GB2312:" + transcodingUtil.hexStringToString(substring5));
                    System.out.println("120-197频段数据BIG5  :" + transcodingUtil.hexStringToStringBIG(substring5));
                    System.out.println("120-197频段数据UNICOD:" + transcodingUtil.hexStringToStringUNICODE(substring5));
                    System.out.println("120-197频段数据十进制      :" + transcodingUtil.transcoding(substring5));
                    System.out.println("120-197频段数据十六进制  :" + substring5);
                    System.out.println("---------------------------------------------------------------------------------");
    
                    /*********
                     198-220
                     * ************************************************/
                    String substring3 = hexString.substring(198, 310);
                    System.out.println("198-+频段数据UTF_8 :" + transcodingUtil.hexStringToStringUTF(substring3));
                    System.out.println("198-+频段数据GBK   :" + transcodingUtil.hexStringToStringGBK(substring3));
                    System.out.println("198-+频段数据ISO   :" + transcodingUtil.hexStringToStringISO(substring3));
                    System.out.println("198-+频段数据GB2312:" + transcodingUtil.hexStringToString(substring3));
                    System.out.println("198-+频段数据BIG5  :" + transcodingUtil.hexStringToStringBIG(substring3));
                    System.out.println("198-+频段数据UNICOD:" + transcodingUtil.hexStringToStringUNICODE(substring3));
                    System.out.println("198-+频段数据十进制      :" + transcodingUtil.transcoding(substring3));
                    System.out.println("198-+频段数据十六进制  :" + substring3);
    
                    /*********
                                                      获取主机mac地址
                    *************************************************/
                    EthernetPacket datalink = (EthernetPacket)ip.datalink;
                    StringBuffer srcMacStr = new StringBuffer();
                    int count = 1;
                    for (byte b : datalink.src_mac) {
                        String string = Integer.toHexString(b & 0xff);
                        if (string.length() == 1) {
                            string = "0" + string;
                        }
                        srcMacStr.append(string);
                        if (count++ != datalink.src_mac.length) srcMacStr.append(":");
                    }
                    System.out.println("获取主机mac地址为: " + srcMacStr);
                    System.out.println("00:74:9c:e5:e0:01".equals(srcMacStr.toString()));
    
                    /*********
                     *  数据汇总
                     *************************************************/
                    
                    
                    
                    String romateName ="3030315FB1A8BEAFD6F7BBFA";
                    
                    String transRomateName = transcodingUtil.hexStringToStringGBK(romateName);
                    System.out.println(transRomateName);
    
                    System.out.println("*************************数据汇总***************************************");
    
                    System.out.println("数据包十六进制:" + hexString);
                    System.out.println("数据包十六进制字符串数据包:" + hexStringToString);
                    System.out.println("数据去向:" + ip.datalink);
                    System.out.println("限制:" + ip.hop_limit);
                    System.out.println("报文头十六进制:" + hexStringHead);
                    System.out.println("报文头十进制:" + transcodingUtil.transcoding(hexStringHead));
                    System.out.println("报文头十六进制字符串:" + StringHead);
                    System.out.println("ip对象包:" + ip);
                    /* System.err.println("报文头中时间戳序列 :"+transcodingUtil.stampToDate(ip.sec)); */
                    /* System.out.println("ip对象包:"+ip.sec); */
                    System.out.println("系统时间:" + new Date());
                    
                    f++ ;
    
                    System.out.println("----------------------------本次抓取数据结束--累计" + f  + "---------------------------------------------------");
                    System.out.println();
    
                    /*********
                     *	将消息发送客户端汇总
                     *************************************************/
                    Message message = new Message();
                    message.setCurrentTime(new Date(System.currentTimeMillis()).toLocaleString());
                    message.setEventDescription(transcodingUtil.hexStringToStringGBK(substring6).trim());
                    message.setSystemCode(transcodingUtil.hexStringToStringGBK(substring));
                    message.setEventId(UUID.randomUUID().toString());
                    message.setSrcMac(srcMacStr.toString());
                    
                    ObjectMapper objectMapper = new ObjectMapper();
                    String json = objectMapper.writeValueAsString(message);
                    
                    /*String test = transcodingUtil.hexStringToString(substring);*/
                    ctx.writeAndFlush(Unpooled.wrappedBuffer(json.getBytes()));
    
                }
            }
    
        }
    
        @Override
    
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    
            cause.printStackTrace();
    
            ctx.close();
    
        }
    }

    4、消息实体 Message.java

    package com.airtimes.netty.network.response;
    
    public class Message {
        
        /**
         * 事件id
         */
        private String eventId;
        
        /**
         * src_mac
         */
        
        private String srcMac;
        
        /**
         * 系统码
         */
        private String systemCode;
        
        /**
         * 事件描述
         */
        private String eventDescription;
        
        /**
         * 子系統
         */
        private Integer masterArea;
        
        /**
         * 防区
         */
        private Integer slaverId;
        
        /**
         * 事件时间
         */
        private String currentTime;
    
        public String getEventId() {
            return eventId;
        }
    
        public void setEventId(String eventId) {
            this.eventId = eventId;
        }
    
        public String getSystemCode() {
            return systemCode;
        }
    
        public void setSystemCode(String systemCode) {
            this.systemCode = systemCode;
        }
    
        public String getEventDescription() {
            return eventDescription;
        }
    
        public void setEventDescription(String eventDescription) {
            this.eventDescription = eventDescription;
        }
    
        public Integer getMasterArea() {
            return masterArea;
        }
    
        public void setMasterArea(Integer masterArea) {
            this.masterArea = masterArea;
        }
    
        public Integer getSlaverId() {
            return slaverId;
        }
    
        public void setSlaverId(Integer slaverId) {
            this.slaverId = slaverId;
        }
    
        public String getCurrentTime() {
            return currentTime;
        }
    
        public void setCurrentTime(String currentTime) {
            this.currentTime = currentTime;
        }
    
        public String getSrcMac() {
            return srcMac;
        }
    
        public void setSrcMac(String srcMac) {
            this.srcMac = srcMac;
        }
    
        @Override
        public String toString() {
            return "Message [eventId=" + eventId + ", srcMac=" + srcMac + ", systemCode=" + systemCode
                   + ", eventDescription=" + eventDescription + ", masterArea=" + masterArea + ", slaverId=" + slaverId
                   + ", currentTime=" + currentTime + "]";
        }
    
        
    }
    

    5、工具类转换 TranscodingUtil .java 

    package com.airtimes.netty.network.tools;
    
    
    import java.math.BigInteger;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    
    public class TranscodingUtil {
    
        /**
         * 接收的byte包转换成16进制字符串
         * 
         * @param req
         * @return
         */
        public static String toHexString(byte[] req) {
            // 进行编码转译 byte --> hexString (字母大写)
            String str = "";
            for (int i = 0; i < req.length; i++ ) {
                String hex = Integer.toHexString(req[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = "0" + hex;
                }
                str += hex.toUpperCase();
            }
            return str;
        }
    
        /**
         * 接收16进制字符串转换成10进制字符串
         * 
         * @param string
         * @return coding
         */
        public static String transcoding(String string) {
    
            // 传过来字符串的16进制字符个数
            int length = string.length() / 2;
    
            // 将字符串存进数组
            String[] s = new String[length];
            for (int i = 0; i < length; i++ ) {
                String ss = string.substring(i * 2, 2 + i * 2);
                s[i] = String.valueOf(ss);
            }
    
            // 定义接收转译之后的数组
            String[] str = new String[s.length];
            // 进行16进制向10进制转换
            for (int j = 0, k = s.length; j < k; j++ ) {
                str[j] = new BigInteger(s[j], 16).toString(10);
            }
    
            // 将转移后的数组转换为字符串
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < str.length; i++ ) {
                sb.append(str[i]);
            }
            String coding = sb.toString();
    
            return coding;
        }
    
        /**
         * 16进制字符串转换为字符串
         *
         * @param s
         * @return
         */
        public static String hexStringToString(String s) {
            if (s == null || s.equals("")) {
                return null;
            }
            s = s.replace(" ", "");
            byte[] baKeyword = new byte[s.length() / 2];
            for (int i = 0; i < baKeyword.length; i++ ) {
                try {
                    baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                s = new String(baKeyword, "GB2312");
                new String();
            }
            catch (Exception e1) {
                e1.printStackTrace();
            }
            return s;
        }
    
        public static String hexStringToStringUTF(String s) {
            if (s == null || s.equals("")) {
                return null;
            }
            s = s.replace(" ", "");
            byte[] baKeyword = new byte[s.length() / 2];
            for (int i = 0; i < baKeyword.length; i++ ) {
                try {
                    baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                s = new String(baKeyword, "utf-8");
                new String();
            }
            catch (Exception e1) {
                e1.printStackTrace();
            }
            return s;
        }
    
        public static String hexStringToStringGBK(String s) {
            if (s == null || s.equals("")) {
                return null;
            }
            s = s.replace(" ", "");
            byte[] baKeyword = new byte[s.length() / 2];
            for (int i = 0; i < baKeyword.length; i++ ) {
                try {
                    baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                s = new String(baKeyword, "gbk");
                new String();
            }
            catch (Exception e1) {
                e1.printStackTrace();
            }
            return s;
        }
    
        public static String hexStringToStringISO(String s) {
            if (s == null || s.equals("")) {
                return null;
            }
            s = s.replace(" ", "");
            byte[] baKeyword = new byte[s.length() / 2];
            for (int i = 0; i < baKeyword.length; i++ ) {
                try {
                    baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                s = new String(baKeyword, "GB18030");
                new String();
            }
            catch (Exception e1) {
                e1.printStackTrace();
            }
            return s;
        }
    
        public static String hexStringToStringBIG(String s) {
            if (s == null || s.equals("")) {
                return null;
            }
            s = s.replace(" ", "");
            byte[] baKeyword = new byte[s.length() / 2];
            for (int i = 0; i < baKeyword.length; i++ ) {
                try {
                    baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                s = new String(baKeyword, "big5");
                new String();
            }
            catch (Exception e1) {
                e1.printStackTrace();
            }
            return s;
        }
    
        public static String hexStringToStringUNICODE(String s) {
            if (s == null || s.equals("")) {
                return null;
            }
            s = s.replace(" ", "");
            byte[] baKeyword = new byte[s.length() / 2];
            for (int i = 0; i < baKeyword.length; i++ ) {
                try {
                    baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                s = new String(baKeyword, "unicode");
                new String();
            }
            catch (Exception e1) {
                e1.printStackTrace();
            }
            return s;
        }
    
        public static String[] bytesToHexStrings(byte[] src) {
    
            if (src == null || src.length <= 0) {
    
                return null;
    
            }
    
            String[] str = new String[src.length];
    
            for (int i = 0; i < src.length; i++ ) {
    
                String hex = Integer.toHexString(src[i] & 0xFF);
                if (hex.length() == 1) {
    
                    hex = "0" + hex;
                }
    
                hex.join(",", str);
    
                /* string.Join(",", s); */
            }
    
            return str;
    
        }
    
        public static String toString(byte[] a) {
            if (a == null) return "null";
            int iMax = a.length - 1;
            if (iMax == -1) return "[]";
    
            StringBuilder b = new StringBuilder();
            b.append('[');
            for (int i = 0;; i++ ) {
                b.append(a[i]);
    
                if (i == iMax) return b.append(']').toString();
                b.append(", ");
            }
        }
    
        /*
         * 将时间戳转换为时间
         */
        public static String stampToDate(Long s) {
            String res;
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            long lt = new Long(s);
            Date date = new Date(lt);
            res = simpleDateFormat.format(date);
            return res;
        }
    
      public String convertByteBufToString(ByteBuf buf) {
    
            String str;
    
            if (buf.hasArray()) { // 处理堆缓冲区
                str = new String(buf.array(), buf.arrayOffset() + buf.readerIndex(), buf.readableBytes());
            }
            else { // 处理直接缓冲区以及复合缓冲区
                byte[] bytes = new byte[buf.readableBytes()];
                buf.getBytes(buf.readerIndex(), bytes);
                str = new String(bytes, 0, buf.readableBytes());
            }
            return str;
        }
    
        public String Object2Json(Object obj) {
            JSONObject json = JSONObject.fromObject(obj);// 将java对象转换为json对象
            String str = json.toString();// 将json对象转换为字符串
    
            return str;
        }
    
    }
    

    6、运行结果:服务器端启动后台效果

     7、运行结果:客户端接收到服务器端报警信息

     8、运行结果:服务器端启动后台效果

     本文主要是对防区红外线设备、的报警信息通过报警主机之间通信截获报警数据、数据类型、防区报警、以及报警级别数据、进行捕捉解析转发、使用Netty Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序、当有客户端请求连接时、客户端将会收到服务器广播的异常信息、文中主要是以Json字符串类型、

     

    本文出自 “想学Python的Java程序猿” 博客,请务必保留此出处郑重声明转载请注明原地址、谢谢https://blog.csdn.net/qq_37606336/article/details/85045785

     

    展开全文
  • 我用的是UDP通信拿到数据数据的类型是这样的S5W1449!p1r!p1r003B1s!S6WGGG00!p2r!p2r00003 !p1r!p1r003B1s! 第0~2位为p1r或p2r,第3~6位为对应侧(p1r或p2r)的点位,第7位为状态位第8位为CRC校验位(将以上待发送...
  • (1)使用报文分析工具软件,wireshark捕获报文并进行存储为.txt,获得报文数据文件。 (2)编程,在图形界面下,对报文的协议进行解码 (3)对ethernet_II、ip、tcp、udp协议进行解码 (4)对ieee802.3、icmp协议...
  • 基本套接字TCP和UDP

    千次阅读 2017-04-09 21:41:40
     协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要socket类型为...
    转自:TCP的Java支持
    

         协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议现在TCP/IP协议族中的主要socket类型为流套接字(使用TCP协议)和数据报套接字(使用UDP协议)。

        TCP协议提供面向连接的服务,通过它建立的是可靠地连接。Java为TCP协议提供了两个类:Socket类和ServerSocket类。一个Socket实例代表了TCP连接的一个客户端,而一个ServerSocket实例代表了TCP连接的一个服务器端,一般在TCP Socket编程中,客户端有多个,而服务器端只有一个,客户端TCP向服务器端TCP发送连接请求,服务器端的ServerSocket实例则监听来自客户端的TCP连接请求,并为每个请求创建新的Socket实例,由于服务端在调用accept()等待客户端的连接请求时会阻塞,直到收到客户端发送的连接请求才会继续往下执行代码,因此要为每个Socket连接开启一个线程。服务器端要同时处理ServerSocket实例和Socket实例,而客户端只需要使用Socket实例。另外,每个Socket实例会关联一个InputStream和OutputStream对象,我们通过将字节写入套接字的OutputStream来发送数据,并通过从InputStream来接收数据。


    TCP连接的建立步骤

    客户端向服务器端发送连接请求后,就被动地等待服务器的响应。典型的TCP客户端要经过下面三步操作:

       1、创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接;

       2.通过套接字的I/O流与服务端通信;

       3、使用Socket类的close方法关闭连接。


     服务端的工作是建立一个通信终端,并被动地等待客户端的连接。典型的TCP服务端执行如下两步操作:

         1、创建一个ServerSocket实例并指定本地端口,用来监听客户端在该端口发送的TCP连接请求;

         2、重复执行:

               1)调用ServerSocket的accept()方法以获取客户端连接,并通过其返回值创建一个Socket实例;

               2)为返回的Socket实例开启新的线程,并使用返回的Socket实例的I/O流与客户端通信;

               3)通信完成后,使用Socket类的close()方法关闭该客户端的套接字连接。

    DEMO

      客户端

    [java] view plain copy
    1. import java.io.IOException;  
    2. import java.io.InputStream;  
    3. import java.io.OutputStream;  
    4. import java.net.Inet4Address;  
    5. import java.net.Inet6Address;  
    6. import java.net.InetAddress;  
    7. import java.net.NetworkInterface;  
    8. import java.net.Socket;  
    9. import java.net.SocketException;  
    10. import java.net.UnknownHostException;  
    11. import java.util.Enumeration;  
    12.   
    13. public class Exercise {  
    14.     public void tcpExample(){  
    15.         try {  
    16.             Socket socket = new Socket("192.168.138.46",8344);  
    17.             System.out.println("Connection ....to server sending echo string");  
    18.             OutputStream out = socket.getOutputStream();  
    19.             System.out.println("发送数据……");  
    20.             out.write("测试连接并发送数据到服务器成功……".getBytes());  
    21.             socket.close();  
    22.             System.out.println("客户端已经关闭");  
    23.               
    24.         } catch (UnknownHostException e) {  
    25.             // TODO Auto-generated catch block  
    26.             e.printStackTrace();  
    27.         } catch (IOException e) {  
    28.             // TODO Auto-generated catch block  
    29.             e.printStackTrace();  
    30.         }  
    31.           
    32.           
    33.     }  
    34.     public static void main(String[] args) {  
    35.         Exercise e = new Exercise();  
    36.         //e.getInterfaceExample();  
    37.         e.tcpExample();  
    38.           
    39.     }  
    40. }  

    服务端
    [html] view plain copy
    1. package NET;  
    2.   
    3. import java.io.IOException;  
    4. import java.io.InputStream;  
    5. import java.net.ServerSocket;  
    6. import java.net.Socket;  
    7. import java.net.SocketAddress;  
    8.   
    9. public class TCPServer {  
    10.     //设置缓冲区的大小  
    11.     private static final int BUFSIZE = 50;  
    12.       
    13.     public static void tcpsever(){  
    14.         try {  
    15.             ServerSocket serSocket = new ServerSocket(8344);  
    16.             int recvMsgSize = 0;  
    17.             int total=0;  
    18.             byte[] receive =  new byte[BUFSIZE];  
    19.             while(true){  
    20.                 //此方法返回一个服务器的关联socket,用此进行数据交换  
    21.                 Socket clntSock = serSocket.accept();  
    22.                 SocketAddress socadd = clntSock.getRemoteSocketAddress();  
    23.                 System.out.println("clint address:"+socadd);  
    24.                 InputStream in = clntSock.getInputStream();  
    25.                 while((total=in.read(receive, recvMsgSize, BUFSIZE-recvMsgSize))!=-1){  
    26.                     recvMsgSize += total;  
    27.                 }  
    28.                 System.out.println("从客户端收到的数据:"+new String(receive));  
    29.                 clntSock.close();  
    30.                 System.out.println("关闭和此客户端的连接……");  
    31.             }  
    32.               
    33.         } catch (IOException e) {  
    34.             // TODO Auto-generated catch block  
    35.             e.printStackTrace();  
    36.         }  
    37.           
    38.     }  
    39.     public static void main(String args[]){  
    40.         tcpsever();  
    41.     }  
    42.   
    43. }  

    UDP的Java支持

        UDP协议提供的服务不同于TCP协议的端到端服务,它是面向非连接的,属不可靠协议,UDP套接字在使用前不需要进行连接。实际上,UDP协议只实现了两个功能:

        1)在IP协议的基础上添加了端口;

        2)对传输过程中可能产生的数据错误进行了检测,并抛弃已经损坏的数据。


        Java通过DatagramPacket类和DatagramSocket类来使用UDP套接字,客户端和服务器端都通过DatagramSocket的send()方法和receive()方法来发送和接收数据,用DatagramPacket来包装需要发送或者接收到的数据。发送信息时,Java创建一个包含待发送信息的DatagramPacket实例,并将其作为参数传递给DatagramSocket实例的send()方法;接收信息时,Java程序首先创建一个DatagramPacket实例,该实例预先分配了一些空间,并将接收到的信息存放在该空间中,然后把该实例作为参数传递给DatagramSocket实例的receive()方法。在创建DatagramPacket实例时,要注意:如果该实例用来包装待接收的数据,则不指定数据来源的远程主机和端口,只需指定一个缓存数据的byte数组即可(在调用receive()方法接收到数据后,源地址和端口等信息会自动包含在DatagramPacket实例中),而如果该实例用来包装待发送的数据,则要指定要发送到的目的主机和端口。


    UDP的通信建立的步骤

    UDP客户端首先向被动等待联系的服务器发送一个数据报文。一个典型的UDP客户端要经过下面三步操作:

        1、创建一个DatagramSocket实例,可以有选择地对本地地址和端口号进行设置,如果设置了端口号,则客户端会在该端口号上监听从服务器端发送来的数据;

        2、使用DatagramSocket实例的send()和receive()方法来发送和接收DatagramPacket实例,进行通信;

        3、通信完成后,调用DatagramSocket实例的close()方法来关闭该套接字。


    由于UDP是无连接的,因此UDP服务端不需要等待客户端的请求以建立连接。另外,UDP服务器为所有通信使用同一套接字,这点与TCP服务器不同,TCP服务器则为每个成功返回的accept()方法创建一个新的套接字。一个典型的UDP服务端要经过下面三步操作:

    1、创建一个DatagramSocket实例,指定本地端口号,并可以有选择地指定本地地址,此时,服务器已经准备好从任何客户端接收数据报文;

        2、使用DatagramSocket实例的receive()方法接收一个DatagramPacket实例,当receive()方法返回时,数据报文就包含了客户端的地址,这样就知道了回复信息应该发送到什么地方;

        3、使用DatagramSocket实例的send()方法向服务器端返回DatagramPacket实例。

    UDP Socket Demo

    这里有一点需要注意:

    UDP程序在receive()方法处阻塞,直到收到一个数据报文或等待超时。由于UDP协议是不可靠协议,如果数据报在传输过程中发生丢失,那么程序将会一直阻塞在receive()方法处,这样客户端将永远都接收不到服务器端发送回来的数据,但是又没有任何提示。为了避免这个问题,我们在客户端使用DatagramSocket类的setSoTimeout()方法来制定receive()方法的最长阻塞时间,并指定重发数据报的次数,如果每次阻塞都超时,并且重发次数达到了设置的上限,则关闭客户端。


    DEMO‘

    [java] view plain copy
    1. package NET;  
    2.   
    3. import java.io.IOException;  
    4. import java.net.DatagramPacket;  
    5. import java.net.DatagramSocket;  
    6. import java.net.Inet4Address;  
    7. import java.net.InetAddress;  
    8. import java.net.Socket;  
    9. import java.net.SocketException;  
    10. import java.net.UnknownHostException;  
    11.   
    12. import com.sun.jmx.snmp.InetAddressAcl;  
    13.   
    14. public class UDP {  
    15.     private final static int  TIMEOUT = 3000;  
    16.     private final static int BUFSIZE = 50;  
    17.     private final static int tries = 5;  
    18.     /** 
    19.      * udp连接的客户端 
    20.      * @throws SocketException  
    21.      * @throws UnknownHostException  
    22.      */  
    23.     public void udpclnt() throws SocketException, UnknownHostException{  
    24.         int tril = 0;  
    25.         DatagramSocket socket = new DatagramSocket();  
    26.         String art = "UDP连接测试成功……";  
    27.         byte[] by = art.getBytes();  
    28.         InetAddress address = null;  
    29.         address = InetAddress.getByName("lenovo-PC");  
    30.         socket.setSoTimeout(0);  
    31.         DatagramPacket send = new DatagramPacket(by,by.length,address,30000 );  
    32.           try {  
    33.               socket.send(send);   
    34.                 
    35.               } catch (IOException e) {  
    36.                   tril++;  
    37.                   System.out.println("进行重发:剩余重发次数"+ (tries-tril));  
    38.               }  
    39.           socket.close();  
    40.     }  
    41.     /** 
    42.      * udp连接的服务器 
    43.      */  
    44.     public void udpServer(){  
    45.         try {  
    46.             DatagramSocket socket = new DatagramSocket(30000);  
    47.             socket.setSoTimeout(TIMEOUT);  
    48.             DatagramPacket receive = new DatagramPacket(new byte[50], BUFSIZE);  
    49.             socket.receive(receive);  
    50.             System.out.println("连接的客户端IP:"+receive.getAddress().getHostAddress()+"端口:"+receive.getPort());  
    51.            byte[]re= receive.getData();  
    52.             System.out.println("收到的数据:"+new String(re));  
    53.         } catch (SocketException e) {  
    54.             // TODO Auto-generated catch block  
    55.             e.printStackTrace();  
    56.         } catch (IOException e) {  
    57.             // TODO Auto-generated catch block  
    58.             e.printStackTrace();  
    59.         }  
    60.     }  
    61.     public static void main(String []args){  
    62.         final UDP udp = new UDP();  
    63.         Thread thread = new Thread(){  
    64.                    public void run(){  
    65.                      try {  
    66.                         udp.udpclnt();  
    67.                     } catch (SocketException e) {  
    68.                         // TODO Auto-generated catch block  
    69.                         e.printStackTrace();  
    70.                     } catch (UnknownHostException e) {  
    71.                         // TODO Auto-generated catch block  
    72.                         e.printStackTrace();  
    73.                     }  
    74.                    }  
    75.                 };  
    76.         thread.start();  
    77.         udp.udpServer();  
    78.           
    79.     }  
    80. }  


      总结:

    1、编写TCP客户端程序,在实例化Socket类时,要注意,底层的TCP协议只能处理IP协议,如果传递的第一个参数是主机名字而不是你IP地址,Socket类具体实现的时候会将其解析成相应的地址,若因为某些原因连接失败,构造函数会抛出一个IOException异常。

    2、TCP协议读写数据时,read()方法在没有可读数据时会阻塞等待,直到有新的数据可读。另外,TCP协议并不能确定在read()和write()方法中所发送信息的界限,接收或发送的数据可能被TCP协议分割成了多个部分。说到这里,其实是与内部结构相关的

    TCP在发送之后会把所有的数据复制到缓冲区中,而UDP则send之后所有的消息都在发送途中。

    3、编写TCP服务器端的程序将在accept()方法处阻塞,以等待客户端的连接请求,一旦取得连接,便要为每个客户端的连接建立一个Socket实例来进行数据通信。

    4、在UDP程序中,创建DatagramPacket实例时,如果没有指定远程主机地址和端口,则该实例用来接收数据(尽管可以调用setXXX()等方法指定),如果指定了远程主机地址和端口,则该实例用来发送数据。

    5、UDP程序在receive()方法处阻塞,直到收到一个数据报文或等待超时。由于UDP协议是不可靠协议,如果数据报在传输过程中发生丢失,那么程序将会一直阻塞在receive()方法处,这对客户端来说是肯定不行的,为了避免这个问题,我们在客户端使用DatagramSocket类的setSoTimeout()方法来制定receive()方法的最长阻塞时间,并指定重发数据报的次数,如果每次阻塞都超时,并且重发次数达到了设置的上限,则关闭客户端。

    6、UDP服务器为所有通信使用同一套接字,这点与TCP服务器不同,TCP服务器则为每个成功返回的accept()方法创建一个新的套接字。

    7、在UDP程序中,DatagramSocket的每一次receive()调用最多只能接收调用一次send()方法所发送的数据,而且,不同的receive()方法调用绝对不会返回同一个send()方法所发送的额数据。

    8、在UDP套接字编程中,如果receive()方法在一个缓冲区大小为n的DatagramPscket实例中调用,而接受队列中的第一个消息长度大于n,则receive()方法只返回这条消息的前n个字节,超出的其他字节部分将自动被丢弃,而且也没有任何消息丢失的提示。因此,接受者应该提供一个足够大的缓存空间的DatagramPacket实例,以完整地存放调用receive()方法时应用程序协议所允许的最大长度的消息。一个DatagramPacket实例中所运行传输的最大数据量为65507个字节,即UDP数据报文所能负载的最多数据,因此,使用一个有65600字节左右缓存数组的数据总是安全的。

    9、在UDP套接字编程中,每一个DatagramPacket实例都包含一个内部消息长度值,而该实例一接收到新消息,这个长度值便可能改变(以反映实际接收的消息的字节数)。如果一个应用程序使用同一个DatagramPacket实例多次调用receive()方法,每次调用前就必须显式地将消息的内部长度重置为缓冲区的实际长度。

    10、另一个潜在问题的根源是DatagramPacket类的getData()方法,该方法总是返回缓冲区的原始大小,忽略了实际数据的内部偏移量和长度信息。

    11.TCP是需要连接的,UDP不用连接,是不可靠的传输,所以使用UDP要重排乱序消息或者处理丢失消息,因此这就加大了服务器的负担。但是之所以使用UDP是因为在传输信息很少时,TCP握手花费的时间基本是传输的2倍,还有在没有可靠性要求时,UDP很灵活。


    展开全文
  • 使用java网络编程模拟简单网络即时通信通信流程图:解析:1.在上图中我们可以看出对于任何一个客户端,都由两部分构成,发送端和接收端(分别由两个线程来维系)2....在用户之间使用UDP报文来传输数据。代码实现:Cha...

    使用java网络编程模拟简单网络即时通信

    通信流程图:

    解析:

    1.在上图中我们可以看出对于任何一个客户端,都由两部分构成,发送端和接收端(分别由两个线程来维系)

    2.客户端在每一次请求链接时都会轮询,向服务器发送请求,服务器发回当前在线列表

    3.服务器端使用线程池技术为每一个连接请求创建一个线程去处理。

    4.在客户端与服务器之间使用TCP通讯,可靠通信

    5.在用户之间使用UDP报文来传输数据。

    代码实现:

    Chat类:

    package cn.csuft.poorguy.homework;

    import java.io.IOException;

    import java.io.InputStream;

    import java.io.OutputStream;

    import java.net.DatagramSocket;

    import java.net.Socket;

    import java.net.SocketException;

    import java.net.UnknownHostException;

    import java.util.HashMap;

    import java.util.Scanner;

    import com.alibaba.fastjson.JSON;

    import com.google.gson.Gson;

    public class Chat {

    Thread sender;

    Thread receiver;

    DatagramSocket udpSocket;

    Socket tcpSocket;

    public Chat() {

    try {

    Scanner cin = new Scanner(System.in);

    System.out.println("昵称:");

    String nick = cin.nextLine();

    //TODD C/S

    tcpSocket = new Socket("127.0.0.1",9000);

    InputStream in = tcpSocket.getInputStream();

    OutputStream out = tcpSocket.getOutputStream();

    //发送自己的昵称和端口

    udpSocket = new DatagramSocket();

    int udpPort = udpSocket.getLocalPort();

    String msg = new String(nick+","+udpPort);

    out.write(msg.getBytes());

    out.flush();

    //接收在线用户的列表

    byte []buf = new byte[1024];

    int size = in.read(buf);

    String json = new String(buf,0,size);

    //HashMap users = new Gson().fromJson(json,HashMap.class);

    HashMap users = JSON.parseObject(json, HashMap.class);

    System.out.println("在线列表 : "+users);

    //double p = users.get(nick).doubleValue();

    //把用户列表传给SenderTask

    sender = new Thread(new SendTask(udpSocket,users,tcpSocket));

    receiver = new Thread(new ReceiverTask(udpSocket));

    sender.start();

    receiver.start();

    } catch (SocketException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (UnknownHostException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    public static void main(String[] args) {

    Chat chat = new Chat();

    }

    }

    ChatServer类:

    package cn.csuft.poorguy.homework;

    import java.io.IOException;

    import java.net.DatagramSocket;

    import java.net.ServerSocket;

    import java.net.Socket;

    import java.net.SocketException;

    import java.util.HashMap;

    import java.util.Map;

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;

    public class ChatServer {

    ServerSocket serverSocket;

    int serverPort = 9000;

    ExecutorService pool;

    Map users = new HashMap();

    public ChatServer() {

    pool = Executors.newCachedThreadPool();

    }

    public void start() {

    System.out.println("服务器启动:。。。。");

    try {

    serverSocket = new ServerSocket(serverPort);

    while(true) {

    Socket socket = serverSocket.accept();

    OnlineService onlineService = new OnlineService(socket,users);

    pool.execute(onlineService);

    }

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    public static void main(String[] args) {

    ChatServer chatServer = new ChatServer();

    chatServer.start();

    }

    }

    OnlineService类:

    package cn.csuft.poorguy.homework;

    import java.io.InputStream;

    import java.io.OutputStream;

    import java.net.Socket;

    import java.util.HashMap;

    import java.util.Map;

    import com.alibaba.fastjson.JSON;

    import com.google.gson.Gson;

    public class OnlineService implements Runnable{

    Socket socket;

    Map users;

    public OnlineService() {

    // TODO Auto-generated constructor stub

    }

    public OnlineService(Socket socket, Map users) {

    this.socket = socket;

    this.users = users;

    }

    @Override

    public void run() {

    try (InputStream in = socket.getInputStream();

    OutputStream out = socket.getOutputStream()){

    byte []buf = new byte[1024];

    int size = in.read(buf);

    String msg = new String(buf,0,size);

    //解析出msg中的nick信息

    String nick = msg.split(",")[0];

    int port = Integer.parseInt(msg.split(",")[1]);

    //将nick与端口放入在线列表中

    users.put(nick, port);

    //String json = new Gson().toJson(users);

    String json = JSON.toJSONString(users);

    System.out.println(json);

    out.write(json.getBytes());

    out.flush();

    } catch (Exception e) {

    // TODO: handle exception

    }

    }

    }

    ReceiveTask类:

    package cn.csuft.poorguy.homework;

    import java.io.IOException;

    import java.net.DatagramPacket;

    import java.net.DatagramSocket;

    import java.net.SocketException;

    public class ReceiverTask implements Runnable {

    DatagramSocket socket = null;

    public ReceiverTask() {

    // TODO Auto-generated constructor stub

    }

    public ReceiverTask(DatagramSocket socket) {

    this.socket = socket;

    }

    @Override

    public void run() {

    String msg = null;

    byte []buf = new byte[1024*8];

    do {

    DatagramPacket packet = new DatagramPacket(buf, buf.length);

    try {

    socket.receive(packet);

    byte []data = packet.getData();

    msg = new String(data,0,packet.getLength());

    System.out.println("收到: "+msg);

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    } while (!msg.equalsIgnoreCase("bye"));

    System.out.println("接收端关闭");

    }

    }

    SendTask类:

    package cn.csuft.poorguy.homework;

    import java.io.IOException;

    import java.io.InputStream;

    import java.io.OutputStream;

    import java.net.DatagramPacket;

    import java.net.DatagramSocket;

    import java.net.InetAddress;

    import java.net.Socket;

    import java.net.UnknownHostException;

    import java.util.HashMap;

    import java.util.Scanner;

    import com.alibaba.fastjson.JSON;

    public class SendTask implements Runnable {

    HashMap users;

    DatagramSocket socket = null;

    Socket tcpSocket;

    public SendTask() {

    // TODO Auto-generated constructor stub

    }

    public SendTask(DatagramSocket socket, HashMap users, Socket tcpSocket) {

    this.socket = socket;

    this.users = users;

    this.tcpSocket = tcpSocket;

    }

    @Override

    public void run() {

    String msg = null;

    Scanner cin = new Scanner(System.in);

    DatagramPacket packet = null;

    while (true) {

    GetUsersFromServer();

    System.out.println("输入接收方:");

    String nick = cin.nextLine();

    if (users.containsKey(nick)) {

    do {

    int port = users.get(nick);

    System.out.print("发送:");

    msg = cin.nextLine();

    byte[] data = msg.getBytes();

    try {

    // 创建数据包

    packet = new DatagramPacket(data, data.length, InetAddress.getByName("127.0.0.1"), port);

    // 发送

    socket.send(packet);

    } catch (UnknownHostException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    } while (!msg.equalsIgnoreCase("bye"));

    System.out.println("发送结束");

    } else {

    System.out.println("该用户不在线");

    }

    }

    }

    private void GetUsersFromServer() {

    // TODD C/S

    try {

    tcpSocket = new Socket("127.0.0.1", 9000);

    InputStream in = tcpSocket.getInputStream();

    OutputStream out = tcpSocket.getOutputStream();

    // 发送自己的昵称和端口

    int udpPort = socket.getLocalPort();

    String ss = new String("######" + "," + udpPort);

    out.write(ss.getBytes());

    out.flush();

    // 接收在线用户的列表

    byte[] buf = new byte[1024];

    int size = in.read(buf);

    String json = new String(buf, 0, size);

    // HashMap users = new Gson().fromJson(json,HashMap.class);

    users = JSON.parseObject(json, HashMap.class);

    System.out.println("在线列表 : " + users);

    } catch (UnknownHostException e1) {

    // TODO Auto-generated catch block

    e1.printStackTrace();

    } catch (IOException e1) {

    // TODO Auto-generated catch block

    e1.printStackTrace();

    }

    }

    }

    注意:

    这里服务器发回的在线列表使用的是fastJson转换成JSON的,在这个过程中遇到了一些晓得问题,之前选用的Gson,但是发现Gson会默认将int转成double,会出现一些错误,所以改用fastJson,建议以后可以直接使用fastJson避免出现类似的错误。

    展开全文
  • TCP 的 Java 支持协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP 协议族有 IP 协议、TCP 协议和 UDP 协议。现在 TCP/IP 协议...

    TCP 的 Java 支持

    协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP 协议族有 IP 协议、TCP 协议和 UDP 协议。现在 TCP/IP 协议族中的主要 socket 类型为流套接字(使用 TCP 协议)和数据报套接字(使用 UDP 协议)。

    TCP 协议提供面向连接的服务,通过它建立的是可靠地连接。Java 为 TCP 协议提供了两个类:Socke 类和 ServerSocket 类。一个 Socket 实例代表了 TCP 连接的一个客户端,而一个 ServerSocket 实例代表了 TCP 连接的一个服务器端,一般在 TCP Socket 编程中,客户端有多个,而服务器端只有一个,客户端 TCP 向服务器端 TCP 发送连接请求,服务器端的 ServerSocket 实例则监听来自客户端的 TCP 连接请求,并为每个请求创建新的 Socket 实例,由于服务端在调用 accept()等待客户端的连接请求时会阻塞,直到收到客户端发送的连接请求才会继续往下执行代码,因此要为每个 Socket 连接开启一个线程。服务器端要同时处理 ServerSocket 实例和 Socket 实例,而客户端只需要使用 Socket 实例。另外,每个 Socket 实例会关联一个 InputStream 和 OutputStream 对象,我们通过将字节写入套接字的 OutputStream 来发送数据,并通过从 InputStream 来接收数据。

    TCP 连接的建立步骤

    客户端向服务器端发送连接请求后,就被动地等待服务器的响应。典型的 TCP 客户端要经过下面三步操作:

    创建一个 Socket 实例:构造函数向指定的远程主机和端口建立一个 TCP 连接;

    通过套接字的 I/O 流与服务端通信;

    使用 Socket 类的 close 方法关闭连接。

    服务端的工作是建立一个通信终端,并被动地等待客户端的连接。

    典型的 TCP 服务端执行如下两步操作:

    创建一个 ServerSocket 实例并指定本地端口,用来监听客户端在该端口发送的 TCP 连接请求;

    重复执行:

    调用 ServerSocket 的 accept()方法以获取客户端连接,并通过其返回值创建一个 Socket 实例;

    为返回的 Socket 实例开启新的线程,并使用返回的 Socket 实例的 I/O 流与客户端通信; 通信完成后,使用 Socket 类的 close()方法关闭该客户端的套接字连接。

    TCP Socket Demo

    下面给出一个客户端服务端 TCP 通信的 Demo,该客户端在 20006 端口请求与服务端建立 TCP 连接,客户端不断接收键盘输入,并将其发送到服务端,服务端在接收到的数据前面加上“echo”字符串,并将组合后的字符串发回给客户端,如此循环,直到客户端接收到键盘输入“bye”为止。

    客户端代码如下:

    packagezyb.org.client;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintStream;importjava.net.Socket;importjava.net.SocketTimeoutException;public classClient1 {public static void main(String[] args) throwsIOException {//客户端请求与本机在20006端口建立TCP连接

    Socket client = new Socket("127.0.0.1", 20006);

    client.setSoTimeout(10000);//获取键盘输入

    BufferedReader input = new BufferedReader(newInputStreamReader(System.in));//获取Socket的输出流,用来发送数据到服务端

    PrintStream out = newPrintStream(client.getOutputStream());//获取Socket的输入流,用来接收从服务端发送过来的数据

    BufferedReader buf = new BufferedReader(newInputStreamReader(client.getInputStream()));boolean flag = true;while(flag){

    System.out.print("输入信息:");

    String str=input.readLine();//发送数据到服务端

    out.println(str);if("bye".equals(str)){

    flag= false;

    }else{try{//从服务器端接收数据有个时间限制(系统自设,也可以自己设置),超过了这个时间,便会抛出该异常

    String echo =buf.readLine();

    System.out.println(echo);

    }catch(SocketTimeoutException e){

    System.out.println("Time out, No response");

    }

    }

    }

    input.close();if(client != null){//如果构造函数建立起了连接,则关闭套接字,如果没有建立起连接,自然不用关闭

    client.close(); //只关闭socket,其关联的输入输出流也会被关闭

    }

    }

    }

    服务端需要用到多线程,这里单独写了一个多线程类,代码如下:

    packagezyb.org.server;importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.io.PrintStream;importjava.net.Socket;/*** 该类为多线程类,用于服务端*/

    public class ServerThread implementsRunnable {private Socket client = null;publicServerThread(Socket client){this.client =client;

    }

    @Overridepublic voidrun() {try{//获取Socket的输出流,用来向客户端发送数据

    PrintStream out = newPrintStream(client.getOutputStream());//获取Socket的输入流,用来接收从客户端发送过来的数据

    BufferedReader buf = new BufferedReader(newInputStreamReader(client.getInputStream()));boolean flag =true;while(flag){//接收从客户端发送过来的数据

    String str =buf.readLine();if(str == null || "".equals(str)){

    flag= false;

    }else{if("bye".equals(str)){

    flag= false;

    }else{//将接收到的字符串前面加上echo,发送到对应的客户端

    out.println("echo:" +str);

    }

    }

    }

    out.close();

    client.close();

    }catch(Exception e){

    e.printStackTrace();

    }

    }

    }

    服务端处理 TCP 连接请求的代码如下:

    packagezyb.org.server;importjava.net.ServerSocket;importjava.net.Socket;public classServer1 {public static void main(String[] args) throwsException{//服务端在20006端口监听客户端请求的TCP连接

    ServerSocket server = new ServerSocket(20006);

    Socket client= null;boolean f = true;while(f){//等待客户端的连接,如果没有获取连接

    client =server.accept();

    System.out.println("与客户端连接成功!");//为每个客户端连接开启一个线程

    new Thread(newServerThread(client)).start();

    }

    server.close();

    }

    }

    执行结果截图如下:

    54ea0a0ab7ec84135d8bb4ab628db420.png

    展开全文
  • 开放式网络互连TCP/IP模型:简化版OSI各层之间的数据封装,拆封数据封装数据拆封IP介绍网络通信三要素IP分类IP(Internet Protocol)域名解析UDP介绍UDP、TCP协议UDP数据报文协议TCP:传输控制协议TCP连接的三次握手...
  • TCP 的 Java 支持协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP 协议族有 IP 协议、TCP 协议和 UDP 协议。现在 TCP/IP 协议...
  • JAVA实现TCP通信

    万次阅读 多人点赞 2018-05-03 14:29:38
    协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要socket类型为...
  • TCP的Java支持协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要...
  • TCP的Java支持协议至关于相互通讯的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。如今TCP/IP协议族中的主要...
  • http://www.importnew.com/19635.htmlTCP的Java支持协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议...
  • 协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP 协议族有 IP 协议、TCP 协议和 UDP 协议。现在 TCP/IP 协议族中的主要 ...
  • JAVA-Socket通信笔记

    2017-11-27 17:29:00
    协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP 协议族有 IP 协议、TCP 协议和 UDP 协议。现在 TCP/IP 协议族中的主要 ...
  • Java TCP/IP Socket

    2017-12-04 13:53:50
    TCP的Java支持 协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要...
  • 文件传输,电子邮件,聊天软件,视频播放等各种软件应用,常用的协议有 HTTP,FTP,SMTP,DNS,Telent等, 主要的作用是产生和解析数据报文; 传输层 面向连接的TCP协议和无连接的UDP协议,对数据报文在链路上传输...
  • 协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要socket类型为流...
  • Java网络编程:TCP的socket编程

    千次阅读 2017-08-18 17:02:53
    一、Java中的网络编程协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中...
  • UDP编程,包括收发udp报文; 聊天室服务器端,Chatserver.java;聊天室客户端,ChatClient.java; Ftp客户端,Mainframe.java; 14数据库 连接各种数据库DBconnector.java; 获得数据库和表的元数据Getmetadata....
  • 协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要socket类型为...
  •  协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要socket类型为...

空空如也

空空如也

1 2 3 4
收藏数 64
精华内容 25
关键字:

java解析udp报文数据

java 订阅