span 订阅
SPAN技术主要是用来监控交换机上的数据流,大体分为两种类型,本地SPAN和远程SPAN. ----Local Switched Port Analyzer (SPAN) and Remote SPAN (RSPAN),实现方法上稍有不同。 利用SPAN技术我们可以把交换机上某些想要被监控端口(以下简称受控端口)的数据流COPY或MIRROR一 份,发送给连接在监控端口上的流量分析仪,比如CISCO的IDS或是装了SNIFFER工具的PC. 受控端口和 监控端口可以在同一台交换机上(本地SPAN),也可以在不同的交换机上(远程SPAN)。 展开全文
SPAN技术主要是用来监控交换机上的数据流,大体分为两种类型,本地SPAN和远程SPAN. ----Local Switched Port Analyzer (SPAN) and Remote SPAN (RSPAN),实现方法上稍有不同。 利用SPAN技术我们可以把交换机上某些想要被监控端口(以下简称受控端口)的数据流COPY或MIRROR一 份,发送给连接在监控端口上的流量分析仪,比如CISCO的IDS或是装了SNIFFER工具的PC. 受控端口和 监控端口可以在同一台交换机上(本地SPAN),也可以在不同的交换机上(远程SPAN)。
信息
简    述
是一种交换机的端口镜像技术
作    用
给某种网络分析器提供网络数据流
中文名
交换端口分析器
外文名
Switched Port Analyzer
SPAN交换端口分析器
SPAN,全称为Switched Port Analyzer,直译为交换端口分析器。是一种交换机的端口镜像技术。作用主要是为了给某种网络分析器提供网络数据流,SPAN并不会影响源端口的数据交换,它只是将源端口发送或接收的数据包副本发送到监控端口。RSPAN(Remote SPAN),即远程SPAN,和SPAN类似,但可以跨越交换网络为多层交换机提供远程监控。SPAN Session--SPAN会话SPAN会话是指一组受控端口与一个监控端口之间的数据流。可以同时对多个端口的进入流量或是一个端口的外出流量进行监控,也可以对VLAN内所有端口的进入流量进行监控,但不能同时对多个端口的外出流量及VLAN的外出流量进行监控,可以对处于关闭状态的端口设置SPAN,但此时的SPAN会话是非活动,但只要相关的接口被打开,SPAN就会变为活动的。监控端口最好是>=受控端口的带宽,否则可能会出现丢包的情况。SPAN Traffic--SPAN的流量使用本地SPAN可以监控所有的网络流量,包括multicast、bridge protocol data unit (BPDU),和CDP、VTP、DTP、STP、PagP、LACP packets. RSPAN不能监控二层协议。Traffic Types--流量类型被监控的流量类型分为三种,Receive (Rx) SPAN 受控端口的接收流量,Transmit (Tx) SPAN 受控端口的发送流量,Both 一个受控端口的接收和发送流量。Source Port--SPAN会话的源端口(也就是monitored port-即受控端口)受控端口可以是实际的物理端口、VLAN、以太通道端口组EtherChannel,物理端口可以在不同的VLAN中,受控端口如果是VLAN则包括此VLAN中的所有物理端口,受控端口如果是以太通道则包括组成此以太通道组的所有物理端口,如果受控端口是一个TRUNK干道端口,则此TRUNK端口上承载的所有VLAN流量都会受到监控,也可以使用filter vlan 参数进行调整,只对filter vlan 中指定的VLAN数据流量做监控。Destination Port--SPAN会话的目的端口(也就是monitoring port-即监控端口)监控端口只能是单独的一个实际物理端口,一个监控端口同时只能在一个SPAN会话中使用,监控端口不参与其它的二层协议如:Layer 2 protocolsCisco Discovery Protocol (CDP),VLAN Trunk Protocol (VTP),Dynamic Trunking Protocol (DTP),Spanning Tree Protocol (STP),Port Aggregation Protocol (PagP),Link Aggregation Control Protocol (LACP).缺省情况下监控端口不会转发除SPAN Session以外的任何其它的数据流,也可以通过设置ingress参数,打开监控端口的二层转发功能,比如当连接CISCO IDS的时会有这种需求,此时IDS不仅要接收SPAN Session的数据流,IDS本身在网络中还会与其它设备有通讯流量,所以要打开监控端口的二层转发功能。Reflector Port--反射端口反射端口只在RSPAN中使用,与RSPAN中的受控端口在同一台交换机上,是用来将本地的受控端口流量转发到RSPAN中在另一台交换机上的远程监控端口的方法,反射端口也只能是一个实际的物理端口,它不属于任何VLAN(It is invisible to all VLANs.)。RSPAN中还要使用一个专用的VLAN来转发流量,反射端口会使用这个专用VLAN将数据流通过TRUNK端口发送给其它的交换机,远程交换机再通过此专用VLAN将数据流发送到监控端口上的分析仪。关于RSPAN VLAN的创建,所有参与RSPAN的交换机应在同一个VTP域中,不能用VLAN 1,也不能用1002-1005,这是保留的(reserved for Token Ring and FDDI VLANs),如果是2-1001的标准VLAN,则只要在VTP Server上创建即可,其它的交换机会自动学到,如果是1006-4094的扩展VLAN,则需要在所有交换机上创建此专用VLAN.反射端口最好是>=受控端口的带宽,否则可能会出现丢包的情况。VLAN-Based SPAN--基于VLAN的SPAN基于VLAN的SPAN只能监控VLAN中所有活动端口接收的流量(only received (Rx) traffic),如果监控端口属于此VLAN,则此端口不在监控范围内,VSPAN只监控进入交换机的流量,不对VLAN接口上的路由数据做监控。(VSPAN only monitors traffic that enters the switch, not traffic that is routed between VLANs.For example, if a VLAN is being Rx-monitored and the multilayer switch routes trafficfrom another VLAN to the monitored VLAN, that traffic is not monitored and is not receivedon the SPAN destination port. )SPAN和RSPAN与其它特性的互操作性Routing--SPAN不监控VLAN间的路由数据;(不好理解)Routing—Ingress SPAN does not monitor routed traffic. VSPAN only monitors traffic thatenters the switch, not traffic that is routed between VLANs. For example, if a VLAN isbeing Rx-monitored and the multilayer switch routes traffic from another VLAN to themonitored VLAN, that traffic is not monitored and not received on the SPAN destination port.STP--监控端口和反射端口不会参与STP,但SPAN对受控端口的STP没有影响;CDP--监控端口不参与CDP;VTP--RSPAN VLAN可以被修剪pruning;VLAN and trunking--可以修改受控端口、监控端口和反射端口的VLAN和TRUNK设置,受控端口的改变会立即生效,而监控端口和反射端口则要在从SPAN中去除后才会生效;EtherChannel--整个以太通道组可以做为受控端口使用,如果一个属于某个以太通道组的物理端口被配成了受控端口、监控端口或反射端口,则此端口会自动从以太通道组去除,当SPAN删除后,它又会自动加入原以太通道组;QoS--由于受QoS的策略影响,监控端口上收到的数据流会与受控端口实际的数据流不同,比如DSCP值被修改等;Multicast--SPAN可以监控组播的数据流;Port security--安全端口不能做为监控端口使用;802.1x--受控端口、监控端口和反射端口上可以设置802.1x,但有些限制。SPAN的限制和缺省设置Catalyst 3550交换机上最多只能设置两个SPAN Session,缺省SPAN没有使用,如果做了设置,缺省情况下,第一个被设为受控端口的接口进出流量都会受到监控,以后再追加的受控端口只会对接收的流量进行监控,监控端口的默认封装类型为Native,也就是没有打VLAN的标记。1、Configuring SPAN--配置本地SPANSwitch(config)# no monitor session 1 //先清除可能已经存在SPAN设置Switch(config)# monitor session 1 source interface fastethernet0/10//设定SPAN的受控端口Switch(config)# monitor session 1 destination interface fastethernet0/20//设定SPAN的监控端口Switch#sh monSession 1---------Type : Local SessionSource Ports :Both : Fa0/10 //注意此处是BothDestination Ports : Fa0/20Encapsulation : NativeIngress: DisabledSwitch(config)# monitor session 1 source interface fastethernet0/11 - 13//添加SPAN的受控端口Switch#sh monSession 1---------Type : Local SessionSource Ports :RX Only : Fa0/11-13 //注意此处是RX OnlyBoth : Fa0/10 //注意此处还是BothDestination Ports : Fa0/20Encapsulation : NativeIngress: DisabledSwitch(config)# monitor session 1 destination interface fastethernet0/20 ingress vlan 5//设定SPAN的监控端口并启用二层转发Switch#sh monSession 1---------Type : Local SessionSource Ports :RX Only : Fa0/11-13Both : Fa0/10Destination Ports : Fa0/20Encapsulation : NativeIngress: Enabled, default VLAN = 5 //允许正常的流量进入Ingress encapsulation: Native2、VLAN-Based SPAN--基于VLAN的SPANSwitch(config)# no monitor session 2Switch(config)# monitor session 2 source vlan 101 - 102 rxSwitch(config)# monitor session 2 destination interface fastethernet0/30Switch#sh mon ses 2Session 2---------Type : Local SessionSource VLANs :RX Only : 101-102 //注意此处是RX OnlyDestination Ports : Fa0/30Encapsulation : NativeIngress: DisabledSwitch(config)# monitor session 2 source vlan 201 - 202 rxSwitch#sh mo se 2Session 2---------Type : Local SessionSource VLANs :RX Only : 101-102,201-202 //注意此处多了201-202Destination Ports : Fa0/30Encapsulation : NativeIngress: Disabled3、Specifying VLANs to FilterSwitch(config)# no monitor session 2Switch(config)# monitor session 2 source interface fastethernet0/48 rxSwitch(config)# monitor session 2 filter vlan 100 - 102 //指定受控的VLAN范围Switch(config)# monitor session 2 destination interface fastethernet0/30Switch#sh mon ses 2Session 2---------Type : Local SessionSource Ports :Both : Fa0/48Destination Ports : Fa0/30Encapsulation : NativeIngress: DisabledFilter VLANs : 100-102 //只监控VLAN100-102中的流量4、Configuring RSPAN--配置远程RSPANRSPAN的Session分成RSPAN Source Session和RSPAN Destination Session两部分,所以相应的配置也要分别在Session的源和目的交换机上做。4.1、首先要配置专用的RSPAN VLANSwitch(config)# vlan 800Switch(config-vlan)# remote-spanSwitch(config-vlan)# endsw1#sh vl id 800VLAN Name Status Ports---- -------------------------------- --------- -------------------------------800 VLAN0800 active Fa0/47, Fa0/48VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------800 enet 100800 1500 - - - - - 0 0Remote SPAN VLAN----------------Enabled //注意看此处的提示Primary Secondary Type Ports------- --------- ----------------- ------------------------------------------4.2、配置RSPAN Source SessionSwitch(config)# no monitor session 1Switch(config)# monitor session 1 source interface fastethernet0/10 - 13Switch(config)# monitor session 1 source interface fastethernet0/15 rxSwitch(config)# monitor session 1 destination remote vlan 800 reflector-port fastethernet0/20sw1#sh mo se 1Session 1---------Type : Remote Source SessionSource Ports :RX Only : Fa0/11-13,Fa0/15Both : Fa0/10Reflector Port : Fa0/20Dest RSPAN VLAN : 8004.3、配置RSPAN Destination SessionSwitch(config)# monitor session 1 source remote vlan 800Switch(config)# monitor session 1 destination interface fastethernet0/30Switch(config)# endsw2#sh mo se 1Session 1---------Type : Remote Destination SessionSource RSPAN VLAN : 800Destination Ports : Fa0/30Encapsulation : NativeIngress: Disabled(VLAN-Based RSPAN)基于VLAN的RSPAN也和上面的方法类似,只不过受控的是整个VLAN.启用监控端口的二层转发以及Specifying VLANs to Filter 的方法也和本地SPAN相同,此处不再举例。详见CISCO CD.五、Catalyst 4000/4500系列交换机的SPAN配置Configuring SPAN命令如下:set span {src_mod/src_ports | src_vlan | sc0} dest_mod/dest_port [rx | tx | both][inpkts {enable | disable}] [learning {enable | disable}][multicast {enable | disable}] [create]set span中的create参数用于创建多个SPAN Session.show spanset span disable [dest_mod/dest_port | all]举例:This example shows how to configure SPAN so that both the transmit and receivetraffic from port 2/4 (the SPAN source) is mirrored on port 3/6 (the SPAN destination):Console> (enable) set span 2/4 3/6// Overwrote Port 3/6 to monitor transmit/receive traffic of Port 2/4Incoming Packets disabled. Learning enabled.Console> (enable) show spanDestination : Port 3/6Admin Source : Port 2/4Oper Source : NoneDirection : transmit/receiveIncoming Packets: disabledLearning : enabledFilter : -Status : active----------------------------------------------Total local span sessions: 1Console> (enable)This example shows how to set VLAN 522 as the SPAN source and port 2/1 as the SPAN destination:Console> (enable) set span 522 2/1// Overwrote Port 2/1 to monitor transmit/receive traffic of VLAN 522Incoming Packets disabled. Learning enabled.Console> (enable) show spanDestination : Port 2/1Admin Source : VLAN 522Oper Source : Port 2/1-2Direction : transmit/receiveIncoming Packets: disabledLearning : enabledFilter : -Status : active----------------------------------------------Total local span sessions: 1Console> (enable)Configuring RSPAN命令如下:set vlan vlan_num [rspan]show vlanset rspan source {mod/ports... | vlans...} reflector mod/port [rx | tx | both][filter vlans...] [create]set rspan destination {mod_num/port_num} [inpkts {enable | disable}][learning {enable | disable}] [create]show rspanset rspan disable source [rspan_vlan | all]set rspan disable destination [mod_num/port_num | all]有些CISCO的专业文字不太好翻译,可能不太准确,有些地方的理解也有出入,欢迎大家一齐讨论提高。--------------------------------------------------------------------------------Example of SPAN.jpg描述: LOCAL SPAN文件大小: 26.12 KB看过的: 文件被下载或查看 20 次--------------------------------------------------------------------------------Flow of RSPAN Monitored Traffic--------------------------------------------------------------------------------Flow of RSPAN Monitored Traffic.jpg描述: Flow of RSPAN Monitored Traffic文件大小: 35.24 KB看过的: 文件被下载或查看 18 次Only traffic that enters or leaves source ports or traffic that enters or leaves source VLANs can bemonitored by using SPAN; traffic routed to a source VLAN cannot be monitored. For example, ifincoming traffic is being monitored, traffic that gets routed from another VLAN to the source VLANcannot be monitored; however, traffic that is received on the source VLAN and routed to another VLANcan be monitored.
收起全文
精华内容
下载资源
问答
  • C++20 span

    千次阅读 2020-01-16 19:42:40
    C++20的span01 范围检查:span02 span demo 01 范围检查:span 对象的连续序列上的无所有权视图。1 类模板 span 所描述的对象能指代对象的相接序列,序列的首元素在零位置。 span 能拥有静态长度,该情况下序列中的...

    01 范围检查:span

    span是对象的连续序列上的无所有权视图。1

    类模板 span 所描述的对象能指代对象的相接序列,序列的首元素在零位置。 span 能拥有静态长度,该情况下序列中的元素数已知并编码于类型中,或拥有动态长度。
    典型实现只保有二个成员:指向 T 的指针和大小。2

    到2020年1月16日前,有3个span的开源版本。
    微软实现了一个版本的span3微软版gsl目前有9个头文件。

    独立头文件的兼容C ++ 11及更高版本的span实现4

    span lite:适用于C ++ 98,C ++ 11和更高版本的C ++ 20跨度的单文件标头版本。5

    span用来做范围检查。提供对一个连续元素序列(主要指内置数组)的访问能力。元素可用很多方式存储,包括存储在vector和内置数组中。类似于指针,一个span不拥有它指向的字符。在这一点上,它很像string_view和STL的迭代器对。
    std::span可能采用合约来控制对范围错误的响应。span的范围检查几乎无额外性能代价。6

    span能很好的解决内置数组退化和越界访问的问题。7

    02 span demo

    https://github.com/5455945/cpp_demo/blob/master/C%2B%2B20/span/span.cpp

    #include <iostream>
    // 这里的gsl::span是微软的一个开源实现
    // https://github.com/microsoft/GSL/tree/master/include/gsl
    #include <gsl/gsl>
    
    using namespace std;
    
    // 《C++语言导论》 P147 13.3 范围检查:span
    void fpn(int* p, int n) { // p可以是一个内置数组
        for (int i = 0; i < n; i++) {
            p[i] = 1;
        }
    }
    
    void use(int x) {
        int a[100];  // 内置数组
        fpn(a, 100);       // 正确
        //fpn(a, 1000);      // 糟糕,范围越界,(0xC0000005: 写入位置 0x000000E546F00000 时发生访问冲突。)
        //fpn(a + 10, 100);  // fpn中产生范围错误,(Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.)
        //fpn(a, x);         // 可疑的,但看起来无事,(x>100,Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.)
    }
    
    void fs(gsl::span<int> p) {
        for (auto& x : p) {
            x = 2;
        }
    }
    
    void use_span(int x) {
        int a[100];
        fs(a);               // 隐式创建一个span<int>{a, 100}
        //fs({ a, 1000 });     // 错误:期待一个sapn
        //fs({ a + 10, 100 }); // 在fs中发生范围错误,(Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.)
        //fs({ a, x });        // 明显可疑,(x>100,Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.)
    }
    
    // C++核心准则边译边学-X.4:使用span解决数组退化和越界访问
    // https://blog.csdn.net/craftsman1970/article/details/103217292
    void traditional_array(int buffer[], size_t size)
    {
        cout << "size=" << size << endl;
        for (int i = 0; i < int(size); ++i) {
            buffer[i] = i;
        }
        buffer[0] = int(size * 2);
        //buffer[size * 2] = int(size * 4);  // 传统数组越界访问
    }
    
    void span_array(gsl::span<int> buffer)
    {
        cout << "size=" << buffer.size() << endl;
        int value = 0;
        for (auto it = buffer.begin(); it != buffer.end(); it++) {
            *it = value++;
        }
        buffer[0] = value++;
        //buffer[buffer.size() * 2] = value++; // span会触发断言
    }
    
    int main()
    {
        int x = 105;
        use(x);
        use_span(x);
    
        int data[10]; // 内置数组
        for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
            data[i] = 0;
        }
        // 使用数组传递参数
        traditional_array(data, 5);
        // 使用span传递参数
        span_array(data);
    
        gsl::span<int> sdata = data;
        for (auto v : sdata) {
            std::cout << v << ", ";
        }
        std::cout << std::endl;
    
        return 0;
    }
    

    1. 标准库头文件span ↩︎

    2. std::span ↩︎

    3. 准则支持库 ↩︎

    4. 为旧版编译器实现C ++ 20的单独头文件的span ↩︎

    5. span lite,适用于C++98,及更高版本的单独头文件实现的span ↩︎

    6. 《C++语言导论》第二版 P147 ↩︎

    7. C++核心准则边译边学-X.4:使用span解决数组退化和越界访问 ↩︎

    展开全文
  • C# Span 入门

    千次阅读 2018-11-19 15:22:10
    本文简单告诉大家如何使用 Span 新的功能 需要知道 Span 是 7.2 才有的功能,如果在正式项目使用,建议安装 Nuget 的方式

    本文简单告诉大家如何使用 Span 新的功能

    需要知道 Span 是 7.2 才有的功能,如果在正式项目使用,建议安装 Nuget 的方式

    在对内存指定的一段的处理,原来的 C# 是比较弱的,因为没有了 C++ 的指针,特别是对于字符串的分割,需要创建多几个字符串。

    垃圾微软为了提高 C# 的性能,于是提供了新的类型 Span,这个类可以拿出任意数组的一段,作为一个新的 Span 列表。这样的底层就是指针,而且指针是有判断是否超过范围比 C++ 安全。

    首先安装 Nuget System.Memory 库,要求 dotnet framework 4.5 以上,在 UWP 16299 以上,在 dotnet core 2.0 以上

    在这里插入图片描述

    先来写一个简单的程序,创建一个数组,然后使用 Span 指定数组的某一段

                var array = new byte[10];
                Span<byte> bytes = array; 
                bytes = bytes.Slice(start: 2, length: 5);
    
                bytes[0] = 5;
                Console.WriteLine(array[2]);
                Console.WriteLine(bytes[0]);
    

    可以看到对 bytes[0] 的修改就是对 array[2] 的修改,这样可以做到数组重新计算。

    也就是对某个计算,需要加上数组的移动,如二维数组的图片计算,例如行是 w 列是 h ,那么计算第 n 行的元素,在以前的时候,就需要在每个的前面加上 w*n,现在可以使用 spanList.Slice(start:w*n, Length:w) 这样重新拿到的数组就是一行,不需要在每个计算都需要添加很多代码

                var array = new byte[10];
                Span<byte> bytes = array; 
                bytes = bytes.Slice(start: 2, length: 5);
    
                bytes[0] = 5;
                Console.WriteLine(array[2]);
                Console.WriteLine(bytes[0]);
    
                try
                {
                    bytes[5] = 2;
                }
                catch (IndexOutOfRangeException e)
                {
                    Console.WriteLine(e);
                }
    

    有了这个类就不需要担心写出超过范围代码

    stackalloc

    如果要和 stackalloc 需要打开不安全代码

    在这里插入图片描述

    然后点击生成高级,选择 C# 7.2 以上

    现在可以写出这样的代码

            private static unsafe void DroosorHotir()
            {
                Span<byte> bytes = stackalloc byte[2];
                bytes[0] = 2;
                bytes[1] = 3;
    
                Console.WriteLine(bytes[0]);
                Console.WriteLine(bytes[1]);
            }
    

    调用这个函数可以输出 2 和 3 ,使用 stackalloc 可以比申请数组使用更少的资源。因为默认申请的数组都在堆中,不使用需要 gc 才可以回收。但是 stackalloc 可以在变量所在函数结束之后直接就回收,不需要移动内存。

    但是 stackalloc 容易出现堆栈溢出,请执行下面的代码,堆栈溢出是 catch 也无法让他不让程序直接退出

                Span<double> bytes = stackalloc double[200000];
    
    

    即使使用 catch ,软件也会直接退出

                try
                {
                    Span<double> bytes = stackalloc double[200000];
                }
                catch (Exception)
                {
                   // 接不住
                }
    

    AllocHGlobal

    除了使用 stackalloc 之外,还可以使用 Marshal.AllocHGlobal 申请一段内存

                IntPtr ptr = Marshal.AllocHGlobal(2);
                try
                {
                    var bytes = new Span<byte>((byte*) ptr, 2) {[0] = 42};
    
                    Console.WriteLine(bytes[0]);
                    Console.WriteLine(Marshal.ReadByte(ptr));
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
    

    需要注意,申请的内存都需要自己释放

    而且需要注意,不要使用比自己申请的内存大的数组

                IntPtr ptr = Marshal.AllocHGlobal(2);
                var bytes = new Span<byte>((byte*) ptr, 1000) {[0] = 42};
    
    

    上面代码申请了内存为 2 但是下一句使用了1000长度

    
                    for (int i = 0; i < 1000; i++)
                    {
                        bytes[i] = 25;
                        Console.WriteLine(bytes[i]);
                    }
    

    这时虽然很多次都可以赋值成功,但是运行到某个时候,软件就直接退出。

    参考:

    C# - All About Span: Exploring a New .NET Mainstay

    我搭建了自己的博客 https://lindexi.gitee.io/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

    如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

    展开全文
  • Span使用之系统提供的Span基本样式

    千次阅读 2017-04-18 22:28:18
    Span的应用在Android中,使用TextView显示文本,但往往有一些特殊的文本样式,比如一段文本,中间某几个字颜色不同或者中间某几个字能点击等等,这些样式如果没有不同,就编写一个新的TextView,那么一段文字将使用...

    Span的应用

    Android中,使用TextView显示文本,但往往有一些特殊的文本样式,比如一段文本,中间某几个字颜色不同或者中间某几个字能点击等等,这些样式如果没有不同,就编写一个新的TextView,那么一段文字将使用很多的TextView去显示,那么,有没有可能使用一个TextView显示所有文字,而基于文字定义不同的样式呢。这就是Span的作用。

    Span使用三部曲

    Spanandroid提供的用于操作文本的样式的相关类。他能够精确地控制一段文本中具体某些文本的样式。基于Span将分为三遍博客去描述

    系统Span的基本使用

    首先,看一下我们要实现的效果,该效果网上的例子很多,本篇博客也是基于网上的例子编写的。

    这里写图片描述

    如上效果,如果每一个特殊效果都是一个TextView,那么将编写很多的TextView,下面我们就开始利用Span实现如上效果。

    编写SpannerTestActivity如下:

    public class SpannerTestActivity extends AppCompatActivity {
    
        private TextView mText;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_spanner);
            mText = ((TextView) findViewById(R.id.text));
            // testSpanned()便是基于文本定义的样式
            mText.setText(testSpanned());
        }
    }
    

    关键方法便是testSpanned()方法,看一下实现

        public Spanned testSpanned() {
            SpannableString spanned = new SpannableString("测试文字字体大小一半两倍前景色背景色正常粗体斜体粗斜体下划线删除线x1x2电话邮件网站X轴综合");
            // ......省略
            return spanned;
        }
    

    构造SpannableString对象,并返回。

    SpannableStringString对象类似,同样可以作为文本设置到 setText()上,不过SpannableString可以通过setSpan()向文本上设置一些特殊样式。

    setSpan()具体声明为setSpan(Object what, int start, int end, int flags)包含四个参数,参数分别为

    • what:设置的样式。
    • start:设置样式的文本开始索引。
    • end:设置样式的文本结束索引。
    • flags :指定样式的范围,当本文发生变化时,是否将样式应用到新增加的文本上。

    看完声明,其实关键点便是what的类型,但参数声明上是object,那么what可以传入哪些值呢?

    系统为我们提供了一些what的值,他们是CharacterStyle及其子类,下面将列举一些:

    在上面的代码中,我们省略了设置样式的相关代码,具体代码如下:

    
            // 设置字体(default,default-bold,monospace,serif,sans-serif)
            spanned.setSpan(new TypefaceSpan("monospace"), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spanned.setSpan(new TypefaceSpan("serif"), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    
            // 设置字体大小,第二个参数表示是否是dp值,默认是px
            spanned.setSpan(new AbsoluteSizeSpan(20), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spanned.setSpan(new AbsoluteSizeSpan(20, true), 6, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    
            // 相对大小 相对于默认字体的倍数
            spanned.setSpan(new RelativeSizeSpan(0.5f), 8, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spanned.setSpan(new RelativeSizeSpan(2f), 10, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置字体的前景色 Magenta紫红
            spanned.setSpan(new ForegroundColorSpan(Color.MAGENTA), 12, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置字体的背景色
            spanned.setSpan(new BackgroundColorSpan(Color.CYAN), 15, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置字体的样式
            spanned.setSpan(new StyleSpan(Typeface.NORMAL), 18, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spanned.setSpan(new StyleSpan(Typeface.BOLD), 20, 22, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spanned.setSpan(new StyleSpan(Typeface.ITALIC), 22, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spanned.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 24, 27, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置下划线
            spanned.setSpan(new UnderlineSpan(), 27, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置删除线
            spanned.setSpan(new StrikethroughSpan(), 30, 33, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置下标
            spanned.setSpan(new SubscriptSpan(), 34, 35, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置上标
            spanned.setSpan(new SuperscriptSpan(), 36, 37, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置链接
            spanned.setSpan(new URLSpan("tel:1234556"), 37, 39, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spanned.setSpan(new URLSpan("mailto:zziamhao@163.com"), 39, 41, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spanned.setSpan(new URLSpan("http://www.baidu.com"), 41, 43, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 设置宽度的缩放,高度不变
            spanned.setSpan(new ScaleXSpan(2.0f), 43, 45, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    

    将上面所有的代码组合到一起,便是实现了开始的那一段文字的效果。

    细节不在讲述,提两个关键点。

    首先是索引startend,记住顾前不顾后即可。

    其次是flags,当文本变化时,对应索引是否应用样式,上面传入的都是同一种,可以传入如下几种,

    • Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 前后都不包括
    • Spanned.SPAN_INCLUSIVE_EXCLUSIVE 前面包括,后面不包括
    • Spanned.SPAN_EXCLUSIVE_INCLUSIVE 后面包括,前面不包括
    • Spanned.SPAN_INCLUSIVE_INCLUSIVE 前后都包括

    这个地方,很多人可能会有疑问,这里不再多做解释,可以将上面的TextView改变为EditText,手动修改一些文本看一下变化就一目了然了。

    展开全文
  • elasticsearch span 跨度查询简介

    千次阅读 2019-08-11 17:58:39
    span_term查询 这个查询如果单独使用,效果跟term查询差不多,但是一般还是用于其他的span查询的子查询。 用法也很简单,只需要指定查询的字段即可: { "span_term" : { "user" : "kimchy" } } 另外,还可以指定...

    span_term查询

    这个查询如果单独使用,效果跟term查询差不多,但是一般还是用于其他的span查询的子查询。

    用法也很简单,只需要指定查询的字段即可:

    {
        "span_term" : { "user" : "kimchy" }
    }
    

    另外,还可以指定查询出的分值倍数:

    {
        "span_term" : { "user" : { "value" : "kimchy", "boost" : 2.0 } }
    }
    

    span_multi查询

    span_multi可以包装一个multi_term查询,比如wildcard,fuzzy,prefix,term,range或者regexp等等,把他们包装起来当做一个span查询。

    用法也比较简单,内部嵌套一个普通的multi_term查询就行了:

    {
        "span_multi":{
            "match":{
                "prefix" : { "user" :  { "value" : "ki" } }
            }
        }
    }
    

    也可以使用boost乘以分值,以改变查询结果的分数:

    {
        "span_multi":{
            "match":{
                "prefix" : { "user" :  { "value" : "ki", "boost" : 1.08 } }
            }
        }
    }
    

    span_first查询

    这个查询用于确定一个单词相对于起始位置的偏移位置,举个例子:

    如果一个文档字段的内容是:“hello,my name is tom”,我们要检索tom,那么它的span_first最小应该是5,否则就查找不到。

    使用的时候,只是比span_term多了一个end界定而已:

    {
        "span_first" : {
            "match" : {
                "span_term" : { "user" : "kimchy" }
            },
            "end" : 3
        }
    }
    

    span_near查询

    这个查询主要用于确定几个span_term之间的距离,通常用于检索某些相邻的单词,避免在全局跨字段检索而干扰最终的结果。

    查询主要由两部分组成,一部分是嵌套的子span查询,另一部分就是他们之间的最大的跨度

    {
        "span_near" : {
            "clauses" : [
                { "span_term" : { "field" : "value1" } },
                { "span_term" : { "field" : "value2" } },
                { "span_term" : { "field" : "value3" } }
            ],
            "slop" : 12,
            "in_order" : false,
            "collect_payloads" : false
        }
    }
    

    上面的例子中,value1,value2,value3最长的跨度不能超过12.

    span_or查询

    这个查询会嵌套一些子查询,子查询之间的逻辑关系为 或

    {
        "span_or" : {
            "clauses" : [
                { "span_term" : { "field" : "value1" } },
                { "span_term" : { "field" : "value2" } },
                { "span_term" : { "field" : "value3" } }
            ]
        }
    }
    

    span_not查询

    这个查询相对于span_or来说,就是排除的意思。不过它内部有几个属性,include用于定义包含的span查询;exclude用于定义排除的span查询

    {
        "span_not" : {
            "include" : {
                "span_term" : { "field1" : "hoya" }
            },
            "exclude" : {
                "span_near" : {
                    "clauses" : [
                        { "span_term" : { "field1" : "la" } },
                        { "span_term" : { "field1" : "hoya" } }
                    ],
                    "slop" : 0,
                    "in_order" : true
                }
            }
        }
    }
    

    span_containing查询

    这个查询内部会有多个子查询,但是会设定某个子查询优先级更高,作用更大,通过关键字little和big来指定。

    {
        "span_containing" : {
            "little" : {
                "span_term" : { "field1" : "foo" }
            },
            "big" : {
                "span_near" : {
                    "clauses" : [
                        { "span_term" : { "field1" : "bar" } },
                        { "span_term" : { "field1" : "baz" } }
                    ],
                    "slop" : 5,
                    "in_order" : true
                }
            }
        }
    }
    

    span_within查询

    这个查询与span_containing查询作用差不多,不过span_containing是基于lucene中的SpanContainingQuery,而span_within则是基于SpanWithinQuery。

    展开全文
  • Android Span 进阶

    千次阅读 2016-08-08 21:40:06
    在上篇文章《Android Span 架构介绍》,我们讲述了Android Span的基本概念和用法,这篇文章我们就来扩展一下我们对Android Span的了解,这一定会使你感到惊奇的,惊叹Android Span竟然还能完成这些的效果,让你在...
  • span 点击事件

    万次阅读 2019-08-02 14:05:44
    <span>内层span元素</span> 外层div元素 <div id="msg"></div> $(function(){ // 为span元素绑定click事件 $('span').bind("click",function(){ var txt = $('#msg').html() + "内层span元素被点击....
  • span标签的间距问题

    千次阅读 2020-02-15 19:45:05
      平时在实现ui的设计稿的时候会遇见一些小问题,比如莫名其妙的间距,明明没有加margin和padding,但是就是会出现间距,这就是两个span标签的间距问题。我们今天就这个问题进行分析。 二、现象描述 <!DOCTYPE ...
  • span设置固定宽度

    千次阅读 2019-07-27 10:04:31
    span> 标签是被用来组合文档中的行内元素。相信对一般的网页设计师来讲是非常熟悉的朋友了,使用相当频繁,但我们往往很少对SPAN设定样式,一般也没什么必要,大多数都留给DIV老朋友了。 在做"善良公社"项目时...
  • div和span标签以及标签分类

    千次阅读 多人点赞 2020-10-28 19:18:27
    span标签 什么是span标签 作用:一般用于配合css修改网页中的一一些局部信息 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>div和span标签</title>...
  • Div与Span标签详解

    万次阅读 2021-08-12 22:30:33
    Div与Span标签详解一、DIV1.简介2.作用3.案例二、span1.简介2.语法3.案例 一、DIV 1.简介 在html中布局使用最多标签为div, 我们通常将网页重构说成div css制作。 Div本身没有什么特别之处,只是div标签替代了...
  • python 爬取<span></span>中间标签的内容

    千次阅读 2019-12-24 20:30:46
    # python 爬取<span></span>中间标签的内容 html = """ <div> <span class='red'>item1</span> <div> <span id='s1'>item2</span> </div> </...
  • 在网站制作中,span标签应该是用得非常多的了。 那么HTML中的span标签究竟有什么用途呢? 它其实就是用来组合文档中的行内元素,也就是将内容放在span标签之中。 span标签居中 <span style="width:500px; ...
  • 数组是C++从C语言继承过来的特性,使用方便同时又可以提供绝佳的性能...本文介绍如何提前使用C++20新特性span解决数组退化和越界访问的问题。 首先看使用数组的最常见代码: int data[10];for(size_ti=0;i<...
  • Android Span 架构介绍

    千次阅读 2016-08-05 22:05:48
    前几天在微博上看到一个人评论Android Span机制相当强大,有必要细心研究一下,于是就google了一下,发现了一篇很好的文章Spans, a Powerful Concept.,然后以这篇文章为基础研究了一下Android Span的用法。...
  • 使用ImageSpan来拼接图片,但是系统默认的ImageSpan能力非常弱,默认无法居中对齐,也无法设置图片与文字的间距,所以我们通常需要自定义ImageSpan,来解决上述问题。这里封装了一个工具类CenterSp...
  • HTML span元素

    千次阅读 2018-04-10 21:50:56
    span元素span元素也是一个没有语义的元素,类似于 div 元素。不过,span 是行内元素,它只能包围字词或短语,而 div 元素适合包含块级内容。如果想为一小块内容定义 class、id、dir、lang 等属性,或定义特殊的显示...
  • span间距问题

    千次阅读 2019-02-12 15:04:15
    span布局中常常会遇到这种问题: 由于父级元素设置了font-size且span(其实不止是span,确切说是子元素)设置了行内块样式,导致span间的空格和换行会有空隙 like this: &lt;div&gt; &lt;span&gt;11&...
  • div+span

    千次阅读 多人点赞 2019-04-12 16:11:09
    2. 什么是SPAN ?(行内元素) 作用:一般用户配合CSS修改网页中的一些局部信息。 3. div 和 span 的区别 1. div 会单独的占领一行,span不会单独的占有一行。 2. div是一个容器级的标签,而span是一个文本级的...
  • 其实想要这个span文本居中,有不少办法,这里提供了一种比较容易做的办法就是在代码中插入以下一行代码: > style= "text-align:center;line-height:18px; " 水平居中text-align:center; 设置行高line-height...
  • span按钮disabled属性无效

    千次阅读 2019-12-10 16:13:39
    span标签使用disabled属性没有效果,标签仍然可以被点击。...span{ pointer-events:none; } 恢复点击事件: span{ pointer-events:auto; } pointer-events属性介绍 1、阻止用户的点击动作产生任何效果...
  • js给span赋值及修改span字体颜色

    万次阅读 2019-03-05 16:37:37
    js给span赋值: document.getElementById("span_id").innerText = userName; js设置span字体颜色: document.getElementById("span_id").style.color="green"; js获取span的值...
  • Android中各种Span的用法

    千次阅读 2017-11-02 10:29:36
    在android.text.style包下,有一些Span类,可以提供我们完成一些在TextView中的特殊内容。(比如:部分内容颜色、字体、大小不同等等,更有部分字体可点击。) 还有一个SpannableStringBuilder,可以帮助我们设置...
  • <span>aa</span> <span>bb</span> <span>cc</span> <span>dd</span> ...... ``` 如上代码,span的个数不固定,现在只知道“cc”这个值,如何用这个值,选中其所在的span? 我想到的是这样$("span...
  • span设置值、获取span 的值

    万次阅读 2017-03-15 11:37:46
    设置span的值 $("#aa").text("新增用户信息"); 说明:#aa是span的id;text("这里是设置的值");注意:一定要双引号, 获取span 的值 var aa = $("#aa").html(); 获取并设置值 var aa = $("#aa").html()....
  • span标签与span标签换行的时候有间距

    千次阅读 2020-04-08 14:10:48
    <div style="font-size:0">...span style="font-size:12px">111</span> <span style="font-size:12px">222</span> </div> 解决办法: 父元素:设置font-size:0; span:...
  • 其实想要这个span文本居中,有不少办法,这里提供了一种比较容易做的办法就是在代码中插入以下一行代码: 打造全网web前端全栈资料库(总目录)看完学的更快,掌握的更加牢固,你值得拥有(持续更新) style= ...
  • span内容自动换行

    千次阅读 2019-05-21 08:42:37
    // css #txt{ max-width: 100%; display: inline-block; overflow-wrap: break-word; /* css3属性,当内容超过指定容器的边界时是否断行 */ text-align: left; }
  • span中添加连续空格

    千次阅读 2021-01-13 15:48:44
    span文字中直接添加连续空格会被默认显示为一个空格,可以使用&nbsp添加连续空格而不会被默认吞没
  • 在《分布式跟踪系统(一):Zipkin的背景和设计》一文中,已经初步的介绍了Zipkin的设计和数据模型,本文将详细介绍Zipkin的Span模型,以及其他“另类”Span模型的设计。  这里多一句嘴,其实专业点的叫法应该是...
  • span内文字居中条件与实现CSS布局方法span默认不像div是块元素,对span使用文字居中text-align:center样式,文字内容是无法在span居中的。最直观对span设置宽度无效的。了解《span宽度设置》以下解决方法,为了能...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 844,587
精华内容 337,834
关键字:

span