精华内容
下载资源
问答
  • IP流 TS流 PS流之间的关系及区别
    千次阅读
    2012-12-13 09:59:39

    什么是ts流

    我们在网络上通信都是通过发送或接受数据包来实现的。

           I P数据包有首部和数据两部分组成的,首部的前一部分是固定长度20字节,是所有IP数据报必须具有的。首部包括:总长度、标识、MF、DF、片偏移。

           “TS流”和“PS流”是经过MPEG-2系统压缩处理后的两种复合信息流。    据传输媒体的质量不同,MPEG-2中定义了两种复合信息流:传送流(TS)和节目流(PS)。

             在MPEG-2系统中,信息复合/分离的过程称为系统复接/分接,由视频,音频的ES流和辅助数据复接生成的用于实时传输的标准信息流(比如实时广播的电视节目)称为“MPEG-2传送流”(MPEG2-TS)(TS的全称:Transport Stream)。

             而“MPEG-2节目流”(MPEG2-PS)主要应用于存储的具有固定时长的节目,如DVD电影(PS的全称:Program Stream)。

             TS流与PS流的主要区别在于TS流的包结构是固定长度的,而PS流的包结构是可变长度的。PS包与TS包在结构上的这种差异,导致了它们对传输误码具有不同的抵抗能力,因而应用的环境也有所不同。

             TS码流由于采用了固定长度的包结构,当传输误码破坏了某一TS包的同步信息时,接收机可在固定的位置检测它后面包中的同步信息,从而恢复同步,避免了信息丢失。所以,MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的。

             而PS包由于长度是变化的,一旦某一PS包的同步信息丢失,接收机无法确定下一包的同步位置,就会造成失步,导致严重的信息丢失。因此,在信道环境较为恶劣,传输误码较高时,一般采用TS码流;而在信道环境较好,传输误码较低时,一般采用PS码流。

             由于TS码流具有较强的抵抗传输误码的能力,因此目前在传输媒体(如有线电视)中进行传输的MPEG-2码流基本上都采用了TS码流的格式。IP数据包和TS流是什么,之间有什么关系



    TS流文件

      DVD节目中的MPEG2格式,是MPEG2-PS,全称是Program Stream,TS的全称则是Transport Stream。MPEG2-PS主要应用于存储的具有固定时长的节目,如DVD电影,而MPEG-TS则主要应用于实时传送的节目,比如实时广播的电视节目。这两种格式的主要区别是什么呢?你将DVD上的VOB文件的前面一截剪掉(或者干脆就是数据损坏),那么就会导致整个文件无法解码,而电视节目是你任何时候打开电视机都能解码(收看)的,所以,MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的

            IP数据包里可以包含TS视频流呢?IP数据包通过UDP/IP协议后是不是可以分解出TS流?搞不清楚到底IP数据包都包括什么内容.

            IP数据包 很正常的啊

            我们在网络上通信都是通过发送或接受数据包来实现的。

            IP数据报有首部和数据两部分组成的,首部的前一部分是固定长度20字节,是所有IP数据报必须具有的。首部包括:总长度、标识、MF、DF、片偏移。在MPEG-2系统中,信息复合/分离的过程称为系统复接/分接,由视频,音频的ES流和辅助数据复接生成的用于实际传输的标准信息流称为MPEG-2传送流(TS:TransportStream)。

            据传输媒体的质量不同,MPEG-2中定义了两种复合信息流:传送流(TS)和节目流(PS:ProgramStream)TS流与PS流的区别在于TS流的包结构是固定长度的,而PS流的包结构是可变长度的。TS码流 PS包与TS包在结构上的这种差异,导致了它们对传输误码具有不同的抵抗能力,因而应用的环境也有所不同。由于采用了固定长度的包结构,当传输误码破坏了某一TS包的同步信息时,接收机可在固定的位置检测它后面包中的同步信息,从而恢复同步,避免了信息丢失。而PS包由于长度是变化的,一旦某一PS包的同步信息丢失,接收机无法确定下一包的同步位置, 就会造成失步,导致严重的信息丢失。因此,在信道环境较为恶劣,传输误码较高时,一般采用TS码流;而在信道环境较好,传输误码较低时,一般采用PS码流。 

          由于TS码流具有较强的抵抗传输误码的能力,因此目前在传输媒体中进行传输的MPEG-2码流基本上都采用了TS码流的包格


          TS=Transport Stream

           ASI=Asychoronize Serial Interface二者的关系是不是这样:TS相当于数据包的编码方式,而ASI则是数据发送的格式和接口标准,二者通过接口进行连接?

           异步串行接口  ASI=Asychoronize Serial Interface  在目前的DVB-C广播电视系统的传输接口中,有两种 MPEG-2视频传输接口标准:异步串行接口标准 ASI和同步并行接口SPI。SPI一共有11位有用信号,每位信号差分成两个信号用来提高传输抗干扰性,在物理链接上用DB25传输,因此连线多且复杂,传输距离短,容易出现故障。但SPI是并行11位信号,处理简单且扩展性强,因此目前一般的MPEG-2视频编码器的输出和视频***的输入都是标准的并行11位信号。ASI用串行传输,只需一根同轴电缆线传输,连线简单,传输距离长。根据SPI和ASI的优缺点,需要传输信号的SPI和ASI的互相转换

          1 SPI信号结构

        并行传输系统SPI包括一位时钟信号、8位数据信号、一位帧同步信号PSYNC和一位数据有效信号DVALID。帧同步信号对应TS包的同步字节047H,DVALID信号用来区分TS包的长度为188个字节或204 个字节。当TS包长为188字节时,DVALID信号一直为高,同时所有信号都与时钟信号保持同步

          2 ASI接口

       ASI传输流可以有不同数据速率,但传输速率恒定,为270Mbps,因此ASI可以发送和接收不同速率的MPEG-2数据。 ASI传输系统为分层结构。最高层、第2层使用MPEG-2标准ISO/IEC 13818-(Systems),第0层和第1层是基于ISO/IEO CD 14165-1的FC纤维信道。FC支持多种物理传输媒介。

      首先将包同步的MPEG-2传送包的8-bit码字转换成10-bit码字;接着在并/串转换时,当要求输入一个新字、而数据源还没有准备好时,应插入一个K28.5的同步字,以达到ASI的固定270Mbps传输速率。所形成的串行比特流将通过缓冲/驱动电路和耦合网络,送到同轴电缆连接器上。插入同步码字可以有三种方法:传输码流的单个字节前后不能都是同步字;传输码流的单个字节前后必须都是同步字;或者是两者的组合。

      到达同轴电缆的接收数据,首先要经过连接器和耦合网络耦合到恢复时钟和数据的电路上,然后进行串/并变换;为了恢复字节同步,ASI***必须先搜寻到K28.5同步字,一旦搜索到该同步字,即为随后接收的数据标定了边界,从而建立了***输出字节的正确字节排列;最后进行10/8-bit变换,恢复出包同步的MPEG-2 TS码流数据。但是K28.5同步字不是有效数据,因此解码时必须删除。

           3 ASI接口实现方案

       在本方案中,MPEG-2 TS码流由单片MPEG-2编码器MB86390提供,它输出符合SPI标准的并行11位信号,TS包长度为188个字节。在SPI/ASI转换方案中,主要选用CYPRESS公司cyb923/cyb933芯片、异步FIFO和逻辑编程器CPLD实现。

      cyb923主要实现码字的8/10bit转换、插入同步字K28.5和并/串变换。ASI的传输速率恒定为270MHz,而输入MPEG-2 TS码率是不同的,所以要用FIFO实现速率匹配,需要对输入的SPI数据、FIFO和cyb923之间的通信进行逻辑控制。综合性能、价格和程序复杂度的考虑,本方案采用xilinx公司的CPLD逻辑编程器XC95108;用VHDL编程实现对它们的逻辑控制。ASI的解码也是相似的过程,cyb933主要实现10/8bit转换、去除同步字K28.5和串并变换。

          3.1 ASI编码

       在ASI的编码过程中,只需将MPEG-2 TS的八位数据和一位TS码率传输时钟输入到CPLD。因为在本方案中,TS格式为188个字节,因此数据有效信号DVALID一直为高,CPLD忽略这个信号,只管接收TS码流数据,而不用关心TS码流的同步头。PSYNC帧同步信号也一样忽略。CPLD将接收到的数据以TS码率时钟写入FIFO。当 FIFO半满时,CPLD接收到FIFO的半满信号,然后CPLD给cyb923发FIFO可读信号,cyb923以27Mbps读取FIFO中的数据;当CPLD计数到cyb923读取了一定数量的FIFO数据,CPLD则向cyb923发送FIFO不可读信号,防止FIFO读空。MPEG-2传输码率的并行最大速度为27/8=3.375Mbps,而读FIFO速率为27Mbps,因此FIFO不会有溢出。考虑到延时,本方案选用较小容量的 FIFO7202。cyb923在FIFO不可读时,向ASI码流中填充K28.5以维持270Mbps的固定传输速率。最后串行数据经过驱动就可用同轴电缆传送出去。本方案中,同步字K28.5的插入采用传输码流的单个字节前后不能都是K28.5同步字的方式。这种方案相对其它两种方案来说,判断和处理都相对简单.

           3.2 ASI解码

       在ASI的接收端,输入的ASI码流经过均衡后,输入到 cyb933芯片。它由内部的时钟锁相环首先锁定ASI码流时钟,检测同步字K28.5;找到后即确定了ASI比特流顺序,然后进行串/并转换。

      由此可知,检测到K28.5,即字节对齐是ASI解码的重要前提,由此cyb933定义了一套检测字节同步的方法。考虑到传输误码等原因可能造成假K28.5,因此cyb933采用双字节确认方法。即连续两个字节都是K28.5,才确认字节同步了,接着进入正常的单字节解码状态。在解码状态,如果在64个解码字节中,CPLD计数到有16个字节是错误的,则CPLD必须向cyb933发送信息,要求cyb933重新进行字节同步。

      字节同步后,因为K28.5是cyb923插入的同步字节,不能作为有效数据输出,cyb933自动略除这些同步字节。当cyb933检测到有效数据时,cyb933将输出一位当前数据有效的指示,如果把这个信号当作FIFO的写有效,则FIFO中的数据一定都是有效数据了。当FIFO半满时,CPLD接收FIFO的半满信号后,CPLD读取FIFO中的数据,并根据读出的字节是否是047H来确定TS包的同步字节;如果找到TS包同步字,将恢复对应的帧同步信号,此时CPLD计数188恢复出完整的TS包,接下来的字节如果不是 047H,说明输入数据有误,CPLD将丢弃这些数据直到找到047H同步字,在此期间CPLD输出TS空包。重新包同步后,CPLD才又开始计数输出正确的188字节的MPEG-2 TS包,从而恢复出SPI正确的11位信号。同样,当FIFO数据不可读时,CPLD也输出TS空包,以维持输出的MPEG-2码率恒定。

      在SPI转ASI的设计中,直接对SPI数据进行ASI编码,而不考虑误码问题。主要考虑 SPI数据直接从MB390输出,没有经过远距离传输,因而降低了ASI编码逻辑控制的复杂度。在ASI解码过程中,ASI数据经过远距离传输,要考虑误码的因素,所以增加了字节和包的重同步设计,以增加抗干扰能力。本方案在实际应用中很好地实现了SPI/ASI的相互转换。





    更多相关内容
  • 采集卫星电视信号,需要采集的前端设备,即采集信号转换成IP(SPTS)的设备。包括了3个种类:

    采集卫星电视信号,需要采集的前端设备,即采集信号转换成IP(SPTS)的设备。包括了3个种类:

    1.     把卫星信号转换成IP码流信号的设备

    2.     把压缩的音视频(包括复合视频,HDMI,SDI)转换成IP码流的设备

    3.     把加密的卫星节目或者本地的加密节目转换成IP码流的设备

     

    1.    八路IP卫星接收机(IPTV)概述

    八路IP卫星接收机支持8路DVB-S/ DVB-S2卫星射频信号输入,输入信号被解调成TS流,再封装成IP (TS over UDP)格式,并通过1路千兆网口输出64路IP(SPTS)流,主要应用于IPTV直播系统的射频信号转播。一台设备可以解决64套节目的转发,性价比超强。

    特点

    u  支持DVB-S、DVB-S2(选件)卫星信号输入(共8路射频F头输入)

    u  支持TS over UDP输出

    u  支持输入、输出信号的实时监测

    u  支持中英文液晶显示,前面板按键操作和远程网管控制

    u  高可靠性设计,运行稳定

    2.    八路HDMI高清编码器概述

    八路HDMI高清编码器支持8路HDMI高清信号输入,通过H.264视频和MPEG-1音频编码形成TS复用流,输出接口为ASI和IP(TS over UDP)。主要应用于数字电视前端直播系统的高清信号转播。

    特点

    u  采用全硬件压缩,实时性强,性能稳定

    u  支持1080P/I,720P等多种格式

    u  支持所有采样率(32KHz、44.1KHz、48KHz等)的音频信号输入

    u  支持音量调节

    u  采用高清HDMI 接口,支持HDCP

    u  支持中英文液晶显示,前面板按键操作和远程网管控制

    3.    八合一编码器概述

    八合一编码器支持8路模拟复合视频以及单声道或立体声输入,通过MPEG-2视频和MPEG-1音频编码形成8路复用码流(8*SPTS)。输出接口为ASI和IP(TS over UDP)。该设备具有高集成,低成本的优势,可广泛应用于无线/有线/IPTV等数字电视播出系统中。

    特点

    u  采用全硬件压缩,实时性强,性能稳定

    u  8路CVBS视频和8组非平衡立体声音频输入

    u  支持所有采样率(32KHz、44.1KHz、48KHz等)的音频信号输入

    u  支持MPEG-2 MP@ML (4:2:0)编码

     

    u  支持中英文液晶显示,前面板按键操作和远程网管控制

     

    通过前端设备得到单节目流的TS(UDP协议),用800Li转协议流软件(外部信号适配器软件)即可转成RTMP进入800Li Flash P2P 流媒体直播系统在互联网进行网络分发,从而可以在PC,手机,机顶盒上进行观看电视节目。 



    展开全文
  • } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = headers.getFirst("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = ...
    sentinel手册
    spring:
      cloud:
        sentinel:
          # 取消控制台懒加载
          eager: true
          # sentinel 地址
          transport:
            dashboard: 192.168.1.22:8858
            port: 8719
          #将sentinel配置信息持久化到nacos 熔断规则
          datasource:
            ds1:
              nacos:
                server-addr: 52.83.239.30:8848
                dataId: gateway-server-flow
                groupId: DEFAULT_GROUP
                data-type: json
                rule-type: flow 
                ## flow 流控规则 degrade 降级规则 system 系统规则 authority 授权规则 param-flow 热点规则
    

    限流规则

      [
        {
          "resource": "/swagger-ui.html", // 资源名称
          "limitApp": "192.168.1.25", // 来源应用 default 不区分调用者
          "grade": 1, // 阀值类型,0表示线程数,1表示QPS
          "count": 1, // 单机阀值
          "strategy": 0, // 流控模式,0表示直接,1表示关联,2表示链路
          "controlBehavior": 0, // 流控效果,0表示快速失败,1表示Warm UP,2表示排队等待
          "clusterMode": false // 是否集群
        }
      ]
      // 192.168.1.25来源的请求 qps 为 1(每秒的查询数1次) 
    

    降级规则

      [
        {
          "resource": "/swagger-ui.html", // 资源名称
          "count": 3, // 最大Rt(ms)(平均响应时间 ) 比例阀值 异常数 
          "grade": 0, // 熔断策略 0 RT 1 异常比例 2 异常数
          "timeWindow": 10, // 熔断时长S 10秒后回复
        }
      ]
      // 一秒内进来n个请求,平均响应时长均超过rt。对此接口进行熔断降级。10秒后恢复
    

    热点规则

    
    

    黑白名单

      [
        {
          "resource": "/swagger-ui.html",  // 资源名称
          "limitApp": "192.168.1.25,127.0.0.1", //  对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB
          "strategy": 1 // 限流模式 0 白名单 1 黑名单
        }
      ]
      // 192.168.1.25 和 127.0.0.1 的来源禁止请求
    

    关于 limitApp 及自定义异常处理

    WebMVC 设置来源 limitApp

    开发包
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-datasource-nacos</artifactId>
            </dependency>
    
    重写RequestOriginParser 设置来源
    import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
    import com.cloud.common.web.utils.IpUtils;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @author 刘志强
     * @date 2020/9/24 16:51
     */
    @Component
    public class MyRequestOriginParser implements RequestOriginParser {
    
        @Override
        public String parseOrigin(HttpServletRequest request) {
            // 从header中获取名为 origin 的参数并返回
            String ip = IpUtils.getIpAddr(request);
            return ip;
        }
    }
    

    覆盖 DefaultUrlBlockHandler 异常处理器处理器

    import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
    import com.alibaba.csp.sentinel.slots.block.BlockException;
    import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.cloud.common.core.result.AjaxResult;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class MyUrlBlockHandler implements UrlBlockHandler {
        public MyUrlBlockHandler() {
        }
    
        @Override
        public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {
            if (AuthorityException.isBlockException(ex)) {
                writer(request,response,AjaxResult.error("被sentinel拦截"));
            }
        }
    
        public static boolean writer(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AjaxResult ajaxResult) {
            PrintWriter writer = null;
            String originHeader = httpServletRequest.getHeader("Origin");
            httpServletResponse.setHeader("Access-Control-Allow-Origin", originHeader);
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.addHeader("Access-Control-Allow-Credentials", "true");
            httpServletResponse.addHeader("Vary", "Origin");
            httpServletResponse.setContentType("application/json; charset=utf-8");
            try {
                JSONObject jsonObject = (JSONObject) JSON.toJSON(ajaxResult);
                writer = httpServletResponse.getWriter();
                writer.append(jsonObject.toString());
            } catch (IOException e) {
                System.out.println("response error" + e);
            } finally {
                if (writer != null) {
                    writer.close();
                }
            }
            return false;
        }
    }
    

    将异常处理器添加至WebCallbackManager中

    import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author 刘志强
     * @date 2020/9/27 09:16
     */
    
    @Configuration
    public class SentinelConfig {
    
        @Bean
        public MyUrlBlockHandler webCallbackManager() {
            MyUrlBlockHandler myUrlBlockHandler = new MyUrlBlockHandler();
            WebCallbackManager.setUrlBlockHandler(myUrlBlockHandler);
            return myUrlBlockHandler;
        }
    }
    

    WebFlux 设置来源 limitApp (Gateway 也可以这样写)

    开发包
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-datasource-nacos</artifactId>
            </dependency>
    
    取消SentinelWebFluxFilter 及异常处理器 自定过滤器,重写SentinelWebFluxFilter过滤器 及异常处理器

    取消默认的过滤器

    spring:
      cloud:
        sentinel:
          filter:
            enabled: false
    

    重写SentinelWebFluxFilter过滤器

    import com.alibaba.csp.sentinel.adapter.spring.webflux.SentinelWebFluxFilter;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    
    /**
     * @author 刘志强
     * @date 2020/9/25 15:31
     */
    @Configuration
    public class SentinelConfig {
    
        /**
         * 自定义Sentinel过滤器
         * @return
         */
        @Bean
        @Order(-2)
        public WebFilter sentinelWebFluxFilter()
        {
            return new MySentinelWebFluxFilter();
        }
    
        /**
         * 自定义异常处理器
         * @return
         */
        @Bean
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public WebExceptionHandler sentinelBlockExceptionHandler() {
            return new MySentinelBlockExceptionHandler();
        }
    }
    
    
    import com.alibaba.csp.sentinel.EntryType;
    import com.alibaba.csp.sentinel.adapter.reactor.ContextConfig;
    import com.alibaba.csp.sentinel.adapter.reactor.EntryConfig;
    import com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer;
    import com.alibaba.csp.sentinel.adapter.spring.webflux.SentinelWebFluxFilter;
    import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.WebFluxCallbackManager;
    import java.util.Optional;
    
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.server.reactive.ServerHttpRequest;
    import org.springframework.web.server.ServerWebExchange;
    import org.springframework.web.server.WebFilterChain;
    import reactor.core.publisher.Mono;
    
    
    /**
     * 自定义过滤器
     * @author admin
     */
    public class MySentinelWebFluxFilter extends SentinelWebFluxFilter {
        private static final String EMPTY_ORIGIN = "";
    
        public MySentinelWebFluxFilter() {
        }
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
            return chain.filter(exchange).transform(this.buildSentinelTransformer(exchange));
        }
    
        private SentinelReactorTransformer<Void> buildSentinelTransformer(ServerWebExchange exchange) {
            ServerHttpRequest serverHttpRequest = exchange.getRequest();
            String path = exchange.getRequest().getPath().value();
            String finalPath = (String)Optional.ofNullable(WebFluxCallbackManager.getUrlCleaner()).map((f) -> {
                return (String)f.apply(exchange, path);
            }).orElse(path);
    //        String origin = (String)Optional.ofNullable(WebFluxCallbackManager.getRequestOriginParser()).map((f) -> {
    //            return (String)f.apply(exchange);
    //        }).orElse("");
            String origin = getIpAddress(serverHttpRequest);
            return new SentinelReactorTransformer(new EntryConfig(finalPath, EntryType.IN, new ContextConfig(finalPath, origin)));
        }
    
    
        public static String getIpAddress(ServerHttpRequest request) {
            HttpHeaders headers = request.getHeaders();
            String ip = headers.getFirst("x-forwarded-for");
            if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
                // 多次反向代理后会有多个ip值,第一个ip才是真实ip
                if (ip.indexOf(",") != -1) {
                    ip = ip.split(",")[0];
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = headers.getFirst("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = headers.getFirst("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = headers.getFirst("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = headers.getFirst("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = headers.getFirst("X-Real-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddress().getAddress().getHostAddress();
            }
            return ip;
        }
    }
    

    自定义异常处理器

    
    import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
    import com.alibaba.csp.sentinel.slots.block.BlockException;
    
    import java.nio.charset.StandardCharsets;
    
    import org.springframework.core.io.buffer.DataBuffer;
    import org.springframework.http.server.reactive.ServerHttpResponse;
    import org.springframework.web.reactive.function.server.ServerResponse;
    import org.springframework.web.server.ServerWebExchange;
    import org.springframework.web.server.WebExceptionHandler;
    import reactor.core.publisher.Mono;
    
    /**
     * @author admin
     */
    public class MySentinelBlockExceptionHandler implements WebExceptionHandler {
    
    
        private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
            ServerHttpResponse serverHttpResponse = exchange.getResponse();
            serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            byte[] datas = "{\"status\":429,\"message\":\"请求超过最大数,请稍后再试\"}".getBytes(StandardCharsets.UTF_8);
            DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);
            return serverHttpResponse.writeWith(Mono.just(buffer));
        }
    
        @Override
        public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
            if (exchange.getResponse().isCommitted()) {
                return Mono.error(ex);
            }
            if (!BlockException.isBlockException(ex)) {
                return Mono.error(ex);
            }
            return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange));
        }
    
        private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) {
            return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);
        }
    }
    
    展开全文
  • ip功能的实现

    千次阅读 2022-04-20 16:19:26
    IP防护功能的实现

    ip限流

    1.限流的思路

    使用redis 功能,了解Redis中的key(IP+URL),从而记录了某个IP访问的某个接口,value存的是访问的次数,加上一个过期时间就是在注解赋值的值。

    • 限流的思路就是去监控这个ip,使用拦截器来进行拦截,
    • 通过 ip的作为key,访问次数为value的方式对某一用户的某一请求进行唯一的标识。
    • 每次访问的时候判断key 是否存在,是否count超过了限制的访问次数、
    • 若超出访问的限制,则应response放回msg:请求过于频繁,给前端予以展示。

    自定义注解

    @interface 就是要做自定义注解了
    @RetentionRetentionPolicy.RUNTIME) 运行时使用
    @Target(可以查看是放在那个上面的,是方法上面还是类上面)
    int seconds();
    int maxCount();
    boolean needLogin() default true;
    

    2.拦截器

    使用的是handlerInterceptor

    HandlerInterceptor

    1. preHandle 方法是处理拦截器拦截使用的,在controller处理之前就开始进行调用了,springmvc中夫人Interceptor是链式调用的,所有的prehandle 方法都会在controller方法调用之前调用。 prehandle 方法,在请求发生前执行的。

    2. posthandle 返回true 调用的前提:prehandle 返回TRUE

      调用前提:prehandle 返回TRUE

      调用时间:controller方法处理完。

      执行顺序:链式Intercepter情况下,按照声明的顺序倒着执行。

    3. afterCompletion

      调用的前提:prehandle返回TRUE

      调用时间:DispatcherServlet进行视图渲染之后多用于清理资源。

    首先是拦截器

    小于最大的操作,是不是加1操作

    首次进入

    此时访问次数小于最大的次数

    此时访问的次数大于最大的次数,

    之后就开始写controller+6

    使用自定义注解

    @GetMapping

    @AccessLimit(seconds = 3,maxCount = 10)

    public String accessLimit( ){

    拿到限流类的注解的参数,拿到方法的注解,就可以使用的最大的次数。

    拦截路径:

    全面的使用注解:InteceptorConfig WebMvcConfigurer 增加一个拦截器

    配置Redis 6379

    反向代理的情况下使用的request.getRemoteAddr( ),获取的Ip地址就是Nginx所在服务器的ip地址,而不知客户端的ip。

    利用X-forwarded-for 伪造客户端

    在web开发中,获取客户端ip地址,为了防止刷票,需要限制每个IP只能投票一次。

    获取客户端IP

    在Java中获取客户端最直接的方式使用request.getRemoteAddr( ) 这种

    HTTP协议是基于TCP协议,由于request,getRemoteAddr( )获取到的就是TCP层直接连接的客户端的IP,对于web服务器来说直接连接的服务器实际上为Nginx,也就是tcp层拿不到真实客户端的IP

    为了解决上面的问题,很多的HTTP代理会在HTTP协议头中添加X-forward-for,用来跟踪请求的来源。

    X-Forwarded-For:client1,proxy1,proxy2

    包含多个IP地址,每个值通过逗号+空格分开,最左边(client1)是最原始客户端的地址,中间如果有多层代理,每一层代理都会将连接他的客户端IP,追加在X-Forwarded-For右边

    获取真实的IP地址的话,首先从HTTP头中获取X-Forwarded-For,如果X-Forwarded-For 存在就按逗号分隔取最左边的第一个IP地址,不存在直接通过request.getRemoteAdrr();

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-在这里插入图片描述
    D2i1HViI-1650442761725)(ip%E9%99%90%E6%B5%81%E5%8A%9F%E8%83%BD%E7%9A%84%E5%AE%9E%E7%8E%B0/image-20220417202935603.png)]

    伪造X-Forwarded-For

    因为在客户端和服务端进行通信的时候,我们需要进行三次握手

    X-Forwarded-For 介绍

    X-Forwarded-For 是一个 HTTP 扩展头部,用来表示HTTP请求端真实 IP,HTTP/1.1 协议并没有对它的定义,但现如今X-Forwarded-For已被各大 HTTP 代理、负载均衡等转发服务广泛使用。

    一般的客户端发送HTTP请求是没有X-Forwarded-For,当请求到达第一个代理服务器时,代理服务器上会加上X-Forwarded-For,并将值设为客户端的IP地址(也就是左边的第一个值),后面如果还有很多代理,会将IP追加到X-Forwarded-For最右边,最终请求到达web应用服务器,应用通过X-Forwarded-For头取左边第一个IP为真实IP,如果客户端在发起请求的时候,请求头上带上一个伪造的X-Forwarded-For,由于后续的每层代理只会追加不会覆盖,那么最终到达应用服务器时,获取左边的第一个IP地址将会是客户端伪造的IP。也就是Java代码getClientIp()方法很有可能是伪造的IP地址,如果投票系统使用这样进行限制的话,很容易被刷票。

    伪造X-Forwarded-For,使用postman来进行伪造就可以了

    如果让Nginx支持X-Forwarded-For

    proxy_ser_header X-Forwarded-For $proxy_add_x_forwarded_for
    

    如果用户在请求时候伪造的话,那么会出现上面案例的client1前面,出现伪造的ip:

    X-Forwarded-For: 伪造ip1, 伪造ip2, client_ip, proxy1_ip, proxy2_ip
    

    防范:

    • 直接在对外的Nginx反向代理的服务器上配置

    既然我们能够直接获得真实的客户端 IP,那么我们为什么还要获得 X-Forwarded-For 呢?原因在于如果配置了多层的代理,那么这个 X-Real-IP 将会是上一层代理的真实 IP。

    我们直接获得 X-Forwarded-For 将会有 IP 被伪造的风险,而使用 X-Real-IP 将会无法获得真实的 IP 地址。我们将两者的优势进行结合,便可防止客户端 IP 伪造。

    proxy_set_header X-Real-IP $remote_addr
    proxy_set_header X-Forwarded-For $remote_addr
    location / {
                    proxy_set_header        X-Real-IP       $remote_addr;
                    proxy_set_header        Host            $host;
                    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                    ...
                }
     RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        //客户端真实IP
        String ip = request.getHeader("X-Real-IP");
    

    r e m o t e a d d r 替 代 上 面 的 remote_addr替代上面的 remoteaddrproxy_add_x_forwarded_for,KaTeX parse error: Double subscript at position 12: proxy_add_x_̲forwarded_for会在…remote_addr是获取的是直接TCP连接的客户端IP。(类似于在JAVA中的request.getRemoteAddr(),是无法伪造的。即使客户端伪造也会被覆盖掉,而不是追加。

    如果有多层代理,那么只要直接对外访问的Nginx上配置X-Forwarded-For为$remote_addr,内部的还是跟之前一样,不然内部的Nginx又会覆盖掉客户端的真实IP

    • tomcat的源码的方法

    遍历头中的IP地址,从右向左遍历,遍历可以通过正则表达式去除内网IP和代理服务器本身的IP,拿到的第一个非移除会使一个可信任的ip

    RemoteIpValve可以替换Servlet API中request.getRemoteAddr()方法的实现,让request.getRemoteAddr()方法从X-Forwarded-For头中获取IP地址。也就是在业务代码中不需要再自己实现类似于上面的getClientIp()方法来从X-Forwarded-For中获取IP,而是直接使用request.getRemoteAddr()方法。想要使用RemoteIpValve,仅需要在Tomcat配置文件server.xml中Host元素内末尾加上:

    <Valve className="org.apache.catalina.valves.RemoteIpValve" ... />
    

    RemoteIpValve有一套防止伪造X-Forwarded-For的机制,实现思路:遍历X-Forwarded-For头中的IP地址,和方法一不同的是,不是直接取左边第一个IP,而是从右向左遍历。遍历时可以根据正则表达式剔除掉内网IP和已知的代理服务器本身的IP(例如192.168开头的IP),那么拿到的第一个非剔除IP就会是一个可信任的客户端IP。这种方法的巧妙之处在于,即使伪造X-Forwarded-For,那么请求到达应用服务器时,伪造的IP也会在X-Forwarded-For值的左边,真实的IP为放到右边的某个位置,从右向左遍历就可以避免取到这些伪造的IP地址。

    .168开头的IP),那么拿到的第一个非剔除IP就会是一个可信任的客户端IP。这种方法的巧妙之处在于,即使伪造X-Forwarded-For,那么请求到达应用服务器时,伪造的IP也会在X-Forwarded-For值的左边,真实的IP为放到右边的某个位置,从右向左遍历就可以避免取到这些伪造的IP地址。

    展开全文
  • 基于redis实现的ip方案

    千次阅读 2022-02-25 16:46:22
    需求: 同一个IP在 一定的时间内只能访问制定的次数,否则就不处理请求 具体思路: 这里借助的是redis的string数据类型,用 key保存IP地址, value为访问的次数,而访问的时间和规定的次数则是通过参数进行传递的。 ...
  • nginx通过IP实现限

    千次阅读 2020-09-02 21:18:41
    限制单位时间内IP的请求数 limit_req_zone用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 "leaky bucket"。 limit_req 配合limit_req_zone 使用 示例 limit_req_zone $binary_remote_addr zone=...
  • Sentinel 针对IP

    千次阅读 2020-09-08 14:21:01
    Sentinel 可以简单实现针对IP的限,通过改造限策略的针对来源选项 1.首先我们要自定义来源解析RequestOriginParser @Configuration public class SentinelConfig { @Bean public RequestOriginParser ...
  • nginx根据ip和突发流量配置解释

    千次阅读 2022-03-29 22:20:31
    nginx配置ip, 如果有突发流量时, 配置处理策略
  • java实现系统限IP

    千次阅读 2018-10-11 22:34:14
    Java 对IP请求进行限. 高并发系统下, 有三把利器 缓存 降级 限. 缓存: 将常用数据缓存起来, 减少数据库或者磁盘IO 降级: 保护核心系统, 降低非核心业务请求响应 限: 在某一个时间窗口内...
  • Spring Cloud Gateway实现IP

    千次阅读 2020-07-15 09:22:27
    在高并发的系统中,往往需要在系统中做限,一方面是为了防止大量的请求使服务器过载,导致服务不可用,另一方面是为了防止网络攻击。这节课详细探讨在 Spring Cloud Gateway 中如何实现限 常见的限算法 滑动...
  • springboot 根据请求IP做的分布式限

    千次阅读 2019-08-14 11:18:59
    在开发高并发系统时有三把利器用来保护系统:缓存、降级和限 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再...
  • 增加中间件 可以选择普通模式和LUA脚本模式,建议选择普通模式,实际上不需要控制的那么精确。 package Middlewares import ( ... "strconv" "time" "voteapi/pkg/app/response" "voteapi/pkg/gredis...const IP_BLAC
  • 使用Easyswoole 开发项目有一段时间了,官方的ip方法比较简陋,我这里自己手动实现了一套基于令牌桶算法限的方案,这里记录分享下 实现功能 1:根据ip 限速 2:可以配置缓冲池,防止突发流量 3:可以配置黑白名单,...
  • Redis-IP、请求次数限制、唯一登陆 我司有一个线上购物平台,为了防止网页爬虫、恶意用户高频访问与秒杀环节产生的高并发使服务器宕机。并且根据用户反馈有两个人同时登录账号导致数据不一致,数据被更改,用户...
  • nginx对ip的操作

    千次阅读 2017-06-15 19:26:39
     服务器资源有限,但是客户端来的请求在不断的上涨, 为了保证一部分的请求能够正常相应, 不得不放弃一些客户端来的请求, 这个时候我们会选择行的进行一些NGINX的限操作, 这种操作可以很大程度上缓解服务器的压力, ...
  • 但是这种方法的缺陷就是摄像头和主机必须连在一起,那这种在室外部署的时候就会非常麻烦并且不安全,还有一种方法,就是用海康威视或者大华的监控摄像头,然后通过IP地址可以无线获取视频,这样就实现了主机和...
  • IP头以及头的各部分含义

    万次阅读 2018-01-14 22:24:30
    我们来看一下IP的头的结构:  IP的头每行有32位,分为版本,头长度,区分服务等十多项内容。  第一个版本,记录IP头为IPv4的头还是IPv6的头。如果是IPv4的头往往为4,如果是IPv6的头则是6. 第二个IHL为IP ...
  • 1、IP碎片重组的理解  在TCP/IP分层中,数据链路层用MTU(最大传输单元)来限制所能传输的数据包大小,MTU是指一次传送的数据最大长度,不包括数据链路层数据帧的帧头。如以太网的MTU为1500字节。  发送的IP数据...
  • IPFIX: IP Flow Information Export,即P数据信息输出,它是由IETF公布的用于网络中的信息测量的标准协议. IPFIX是IETF的一个工作组,它的主要工作就是制订用于IP网络中的信息测量标准协议,称为IPFIX协议。 ...
  • 媒体解锁的检测脚本收集。 一、MediaUnlock 首先安装curl和jq 带apt的Linux apt-get install -y curl jq 带yum的Linux yum install -y curl jq 运行脚本 bash <(curl -sSL ...
  • IP监测技术及应用—摘录于2012ICTC论文集 IP监测技术及应用   The Technology and Application of IP Flow Monitoring     摘要 随着
  • TCP\IP 数据与数据包

    万次阅读 多人点赞 2017-09-05 09:23:57
    因为这段时间再看suricata的源码,然后发现自己对数据与数据包的概念有点模糊,然后到网上去百度,发现网上的解释少得可怜,大多数都是一些名词解释,没什么收获,后来看多了也了解了一些,所以记录下来,如果有不...
  • H264_Lite高清视频编码器/解码器IP核 我公司针对图传系统(如无人机无线图传),推出H.264高清视频编解码器IP核。可以在FPGA/ASIC上集成使用。 H264_Lite视频编解码器(encoder&amp;amp;decoder)由硬件描述...
  • 在进行TCP/IP协议相关的开发工作中,经常需要发,其中分两种情况: 重点在流量本身,具体的报文格式不甚关心。比如性能测试中,一般涉及的就是UDP或TCP报文; 重点在报文格式,如ICMP报文、IGMP报文等。 不同的...
  • 在http设置中添加限的设置,20r/s 每个ip每秒允许20次访问。 设置完成后再需要限的接口中调用该设置。 http{ limit_req_zone $uri zone=api_read:20m rate=20r/s; } server{ location /test/api { limit_req ...
  • Nginx对同一IP限速限

    千次阅读 2016-11-25 14:36:53
    Nginx通过limit_conn_zone和limit_req_zone对同一个IP地址进行限速限,可防止DDOS/CC和flood攻击,这类文章网上比较多,但是limit_req_zone中burst漏桶原理说得清楚的却很少。 limit_conn_zone是限制同一个IP的...
  • 一、TCP/IP通信传输 TCP/IP协议族按层次分别分为以下4层:应用层、传输层、网络层和数据链路层 1、利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则从链路层往上...
  • 苦于没有网络摄像机的使用经验,怕到时候花了几千大洋买的摄像机不能用,便想先验证一下opencv是否可以获取网络摄像机的实时视频,就用半天多时间做了这个测试。 准备工作 带摄像头的安卓手机一部 电脑一台 电脑...
  • IP网络数据包部分特征分析工具的设计 IP网络数据包部分特征分析工具的设计 IP网络数据包部分特征分析工具的设计 IP网络数据包部分特征分析工具的设计
  • 【Nginx】如何封禁IPIP段?看完这篇我会了!!

    千次阅读 多人点赞 2020-07-13 14:25:19
    Nginx不仅仅只是一款反向代理和负载均衡服务器,它还能提供很多强大的功能,例如:限、缓存、黑白名单和灰度发布等等。在之前的文章中,我们已经介绍了Nginx提供的这些功能。小伙伴们可以到【Nginx专题】进行查阅...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 478,288
精华内容 191,315
关键字:

ip流