精华内容
下载资源
问答
  • 多路复用技术

    2016-09-01 10:15:00
    多路复用技术  复用的概念是从提高通信的有效性角度提出来的,其主要目的是为了有效地... 频分多路复用的基本原理是:如果每路信号以不同的载波频率进行调制,而且各个载波频率是完全独立的,即各个信道所占用的...

    多路复用技术

      复用的概念是从提高通信的有效性角度提出来的,其主要目的是为了有效地利用带宽。多路复用通常分为频分多路复用、时分多路复用、波分多路复用、码分多址和空分多址。

    1. 频分多路复用(FDM,Frequency Division Multiplexing)

      频分多路复用的基本原理是:如果每路信号以不同的载波频率进行调制,而且各个载波频率是完全独立的,即各个信道所占用的频带不相互重叠。相邻信道之间用“警戒频带”隔离,那么每个信道就能独立地传输一路信号。

      频分多路复用的主要特点是,信号被划分成若干通道(频道、波段),每个通道互不重叠,独立进行数据传递。频分多路复用在无线电广播和电视领域中应用较多。ADSL(非对称数字用户环路)也是一个典型的频分多路复用。ADSL用频分多路复用的方法,在PSTN(公共交换电话网络)使用的双绞线上划分出3个频段:0-4kHz用来传送传统的语音信号;20-50kHz用来传送计算机上载的数据信息;150-500kHz或140-1100kHz用来传送从服务器上下载的数据信息。

    2.时分多路复用(TDM,Time Division Multiplexing)

      时分多路复用是以信道传输时间作为分割对象,通过为多个信道分配互不重叠的时间片的方法来实现多路复用的。时分多路复用将用于传输的时间划分为若干个时间片,每个用户分得一个时间片。

      目前,应用最广泛的时分多路复用是贝尔系统的T1载波。T1载波是将24路音频信道复用在一条通信线路上,每路音频信号在送到多路复用器之前,要通过一个脉冲编码调制(PCM,Pulse Code Modulation)编码器,编码器每秒取样8000次。24路信号的每一路,轮流将一个字节插入到帧中,每个字节的长度为8bit,其中7bit是数据位,1bit用于信道控制。每帧由24*8=192bit组成,附加1bit作为帧的开始标志位,所以每帧共有193bit 。由于发送一帧需要125ms,一秒钟可以发送8000帧。因此T1载波的数据传输速率为:193bit*8000/s=1544000bps=1544kbps=1.544Mbps

    3.波分多路复用(WDM,Wayelength Division Multiplexing)

      波分复用就是在同一根光纤内传输多路不同波长的光信号,以提高单根光纤传输能力。也可以这样认为:WDM是FDM应用于光纤信道的一个变例。如果让不同波长的光信号在同一根光纤上传略而互不干扰,利用多个波长适当错开的同时在一根光纤上传送各自携带的信息,就可以大大增加所传输的信息容量。由于是用不同的波长传送各自的信息,因此即使在同一根光纤上也不会相互干扰。在接收端转换成电信号时,可以独立地保持每一个不同波长的所传送的信息。这种方式就叫做“波分复用”。

      将一系列载有信息的不同波长的光载波,在光频域内以一至几百纳米的波长间隔合在一起沿单根光纤传输,在接收端再用一定的方法,将各个不同波长的光载波分开。在光纤的工作窗口上安排100个波长不同的光源,同时在一根光纤上传送各自携带的信息,就能使光纤通信系统的容量提高100倍。

    4.码分多址(CDMA,Code Division Multiple Access)

      码分多址是采用地址和时间、频率共同区分信道的方式。CDMA的特征是每个用户具有特定的地址码,而地址码之间相互具有正交性,因此各用户信息的发射信号在频率、时间和空间上都可能重叠,从而使有限的频率资源得到利用。

      CDMA是在扩频技术上发展起来的无线通信技术,即将需要传送的具有一定信号的信息数据,用一个带宽远大于信号带宽的高速伪随机码进行调制,使原数据信号的带宽被扩展,再经载波调制并发送出去。接收端也使用完全相同的伪随机码,对接收的带宽信号作相关处理,把宽带信号换成原信息数据的窄带信号即解扩,以实现信息通信。不同的移动台(或手机)可以使用同一个频率,但是每个移动台都被分配带有一个独特的“码序列”,该序列码与所有别的“码序列”都不相同,因为是靠不同的“码序列”来区分不同的移动台,所以各个用户相互之间也没有干扰,从而达到了多路复用的目的。

    5.空分多址(SDMA,Space Division Multiple Access)

      空分多址技术将空间分割构成不同的信道,从而实现频率的重复使用,达到信道增容的目的。SDMA系统的处理程序如下:

      (1)系统将首先对来自所有天线中的信号进行快照或取样,然后将其转换成数字形式,并存储在内存中。

      (2)计算机中的SDMA处理器将立即分析样本,对无线环境进行评估,确认用户、干扰源及其所在的位置。

      (3)处理器对天线信号的组合方式进行计算,力争最佳地恢复用户的信号。借助这种策略,每位用户的信号接收质量将大大提高,而其他用户的信号或干扰信号则会遭到屏蔽。

      (4)系统将进行模拟计算,使天线陈列可以有选择地向空间发送信号。在此基础上,每位用户的信号都可以通过单独的通信信道-空间信道实现高效的传输。

      (5)在上述处理的基础上,系统就能够在每条空间信道上发送和接收信号,从而使这些信道成为双向信道。

      利用上述流程,SDMA系统就能够在一条普通信道上创建大量的频分、时分或码分双向空间信道,每一条信道都可以完全获得整个陈列的增益和抗干扰功能。从理论上而言,带m个单元的阵列能够在每条普通信道上支持m条空间信道。但在实际应用中支持的信道数量将略低于这个数目,具体情况则取决于环境。由此可见,SDMA系统可使系统容量成倍增加,使得系统在有限的频谱内可以支持更多的用户,从而成倍地提高频谱使用效率。

      近几十年来,无线通信经历了从模拟到数字,从固定到移到的重大变革。而就移动通信而言,为了更有效地利用有限的无线频率资源,时分多址技术(TDMA)、频分多址技术(FDMA)、码分多址技术(CDMA)得到了广泛的应用,并在此基础上建立了GSM(移动通信技术)和CDMA(是区别于3G的窄带CDMA)两大主要的移动通信网络。就技术而言,现有的这3种多址技术已经得到了充分的应用,频谱的使用效率已经发挥到了极限。空分多址技术(SDMA)则突破了传统的三维思维模式,在传统的三维技术的基础上,在第四维空间上极大的拓宽了频谱的使用方式,使得移动用户仅仅由于空间位置的不同而复用同一个传统的物理信道成为可能,并将移动通信技术引入了一个更为崭新的领域。

    转载于:https://www.cnblogs.com/net-saiya/p/5828668.html

    展开全文
  • 多路复用

    2008-06-18 15:10:29
    1、多路复用的目的:   充分利用昂贵的通信线路,尽可能地容纳较多的用户和传输较多的信息。 2、多路复用的基本原理:  当物理信道的可用带宽超过单个原始信号所需的带宽时,可将该物理信道的总带宽分割成...

    1、多路复用的目的: 

        充分利用昂贵的通信线路,尽可能地容纳较多的用户和传输较多的信息。

    2、多路复用的基本原理:

        当物理信道的可用带宽超过单个原始信号所需的带宽时,可将该物理信道的总带宽分割成若干个固定带宽的子信道,并利用每个子信道传输一路信号,从而达到多路信号共用一个信道,或者将多路信号组合在一条物理信道上传输的目的,充分利用信道容量。

    3、多路复用主要采用的技术:

    (1)频分多路复用(FDM-Frequency Division Multiplexing

    (2)时分多路复用(TDM-Time Division Multiplexing)

                       T1系统

                       E1系统

    (3)波分多路复用(Wavelength Division Multiplexing)

     

    (1)频分多路复用FDM-Frequency Division Multiplexing):

        用途:主要用于模拟信道的复用。

        原理:不同的传输媒体具有不同的带宽(信号不失真传输的频率范围).频分多路复用技术对整个物理信道的可用带宽进行分割,并利用载波调制技术,实现原始信号的频谱迁移,使得多路信号在整个物理信道带宽允许的范围内,实现频谱上的不重叠,从而共用一个信道。为了防止多路信号之间的相互干扰,使用隔离频带来隔离每个子信道。

        工作过程:先对多路信号的频谱范围进行限制(分割频带), 然后通过变频处理,将多路信号分配到不同的频段。

     

    (2)时分多路复用TDM-Time Division Multiplexing)

    用  途:主要用于数字信道的复用。

    原  理:当物理信道可支持的位传输速率超过单个原始信号要求的数据传输速率时,可以将该物理信道划分成若干时间片,并将各个时间片轮流地分配给多路信号,使得它们在时间上不重叠。

    应  用:使用时分多路复用技术来支持语音信号的传输

    T1系统:

        T1系统采用时分多路复用技术,它具有24路语音信号,8bit/路,125(微秒)/周期;

            一个周期:8(bit)* 24路 + 1(同步位)= 193(bit),

            传输速率为: 193(bit)/125(微秒)=1.544Mbps  

     

        TDM技术可以使得更多路信号复用到速率更高的信道上。例如:4路T1(1.544Mbps)复用到T2(6.312Mbps),7路T2再复用到T3(44.736Mbps)

     

    4路T1 系统复用示意图

    E1系统:

        E1系统采用时分多路复用技术,它有32路语音信号,8bit/路,125微秒/周期,传输速率:32*8/125=2.048Mbps。E1系统示意图如下:

    (3)波分多路复用(Wavelength Division Multiplexing)

      波分多路复用实质上是利用了光具有不同的波长的特征。随着光纤技术的使用,基于光信号传输的复用技术得到重视。

      波分多路复用的原理:利用波分复用设备将不同信道的信号调制成不同波长的光,并复用到光纤信道上。在接收方,采用波分设备分离不同波长的光。

    展开全文
  • 多路复用和多路分解

    2021-06-07 16:19:58
    前言:此博客主要为学习总结,方便以后查看。...2.绿色块表示套接字,一个进程可以有一个或者个套接字,从进程角度看(应用层以下都属于网络),它相当于从网路向进程传递数据和从进程向网络传递数

    前言:此博客主要为学习总结,方便以后查看。基于《计算机网络——自定向下方法》第六版

    一 运输层功能(或服务)

    网络层提供从主机到主机的交付服务,运输层扩展了网络层交付服务,提供从进程(运行在主机上的应用程序)到进程的交付服务。如下图所示:
    在这里插入图片描述
    注释:
    1.源主机的P1表示实现某协议(如HTTP协议)的客户进程,目的主机的P1表示某协议(如HTTP协议)的服务器进程。
    2.绿色块表示套接字一个进程可以有一个或者多个套接字,从进程的角度看(应用层以下都属于网络),它相当于从网路向进程传递数据和从进程向网络传递数据的门户。在接受主机(目的主机)中运输层实际上并没有直接将数据交付给进程,而是交付给了一个中间套接字
    3.多路复用:在源主机从不同的套接字(体现多路)收集数据块,并为每个数据块封装首部信息(该信息可用于多路分解)从而生成报文段,然后将报文段传递到网络层。
    4.多路分解:在目的主机中,把网路层获取的报文段中的数据交付到正确的(或者说对应的)套接字中。

    二、 端口号

    1、端口号的由来
    运输层将数据的交付服务从网络层的主机到主机扩展到了进程到进程,主要实现依赖于多路复用和多路分解,简单描述就是,收集不同套接字中的数据,添加首部信息,封装成报文段和从报文段中提取数据交付到正确的套接字。

    我们知道同一时刻,主机上可能存在多个进程,进而存在多个套接字,那么多路分解需要把数据交付给正确的套接字,需要保证两点:

    1. 套接字要有唯一标识符;
    2. 报文段中有特殊字段来指示该报文段中的数据所要交付到的套接字;

    于是就有了端口号

    2. 端口号在报文段中的应用

    在这里插入图片描述
    源端口号字段和目的端口号字段为16比特,因此端口号范围为0 ~ 65535。其中,0 ~ 1023为周知端口号,使用是受限的,保留给了诸如HTTP、FTP等周知应用层协议使用。

    3.端口号的分类
    (1) 服务器端使用的端口号

    包括周知端口号和登记端口号

    周知端口号,分配给周知的应用程序(一般是服务器端应用程序),范围0~1023

    应用程序(协议) 周知端口号
    HTTP 80
    HTTPS 443
    DNS 53
    FTP 21
    TELNET 23

    登记端口号,分配给某些著名公司的常用的应用程序,避免重复,使用时需要登记,范围1023~49151

    应用程序 端口号
    mysql 3306
    (2) 客户端使用的端口号
    客户端使用的端口号(又称,短暂端口号),有操作系统动态分配给客户端进程,范围49152~65535。

    四、多路复用和多路分解实现

    ip地址可以标识一台主机,端口号可以标识一台主机上的某个进程,因此,在网络上的任意一个进程就可以通过ip地址+端口号进行标识。由于网络上进程间数据的传递是依靠套接字进行的,更准确的说,IP地址+端口号标识了一个套接字。
    1. UDP的多路复用和多路分解
    UDP的套接字标识是一个二元组【目的主机IP地址:目的端口号】

    在报文端从源主机A到达目的主机B后,目的主机运输层的UDP协议检查报文段的目的端口号,然后把该报文段中的数据定向交付(分解)到相应的套接字;

    展开全文
  • I/O多路复用之 epoll 系统调用

    千次阅读 2017-05-07 00:32:43
    I/O多路复用除了select和poll系统调用外,epoll 也可以检查多个文件描述符的就绪状态,以达到I/O多路复用的目的。 epoll 系统调用是 Linux 系统专有的,在 2.6 版本新增,epoll 的主要优点有: 当检查大量的文件...

    I/O多路复用除了之前我们提到的selectpoll外,epoll 也可以检查多个文件描述符的就绪状态,以达到I/O多路复用的目的。
    epoll 系统调用是 Linux 系统专有的,在 Linux 内核 2.6 版本新增,epoll 的主要优点有:

    • 当检查大量的文件描述符时,epoll 的性能比selectpoll高很多
    • epoll 既支持水平触发也支持边缘触发,selectpoll只支持水平触发

    epoll 编程接口的核心数据结构为 epoll 实例,它和一个打开的文件描述符相关联。这个文件描述符是内核数据结构的句柄,该内核数据结构的作用主要有两个:

    • 记录在进程中声明过的感兴趣的文件描述符列表,即 interest list
    • 维护处于I/O就绪状态中文件描述符列表,即 ready list

    其中,ready list 是 interest list 的子集。

    epoll 编程接口由以下3个系统调用组成:

    • epoll_create创建一个 epoll 实例,返回代码该实例的文件描述符
    • epoll_ctl增删改 epoll 实例的 interest list
    • epoll_wait返回与 epoll 实例相关联的就绪列表中的成员

    创建 epoll 实例: epoll_create

    系统调用epoll_create创建一个新的 epoll 实例,其对应的 interest list 初始化为空。

    #include <sys/epoll.h>
    int epoll_create(int size);

    参数size指定了我们想要通过 epoll 实例来检查的文件描述符个数,该参数并不是一个上限,而是告诉内核应该如何为内部数据结构划分初始大小。epoll_create返回新创建 epoll 实例的文件描述符,这个文件描述符在其他几个 epoll 系统调用中会被用来表示 epoll 实例。当这个文件描述符不再使用时,应该通过close来关闭。

    从 Linux 2.6.27 版内核以来,Linux 支持了一个新的系统调用 epoll_create1。该系统调用执行的任务同epoll_create,但是去掉了无用的参数size,并增加了一个可用来修改系统调用行为的flag标志。

    修改 epoll 实例: epoll_ctl

    系统调用epoll_ctl能够修改由文件描述符epfd所代表的 epoll 实例中的 interest list。

    #include <sys/epoll.h>
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev);
    • 参数epfd指定 epoll 实例的文件描述符,即对哪个 epoll 实例进行操作
    • 参数fd指明要修改 interest list 中的哪一个文件描述符。
    • 参数op用来指定需要执行的操作,下文我们还会对op操作类型进行进一步描述
    • 参数ev是指向结构体epoll_event的指针,关于结构体epoll_event的定义,我们也在下文描述

    epoll_ctlop支持的操作包括以下以种:

    • EPOLL_CTL_ADD
      将描述符fd添加到 epoll 实例的 interest list 中去。对于fd上我们感兴趣的事件,在ev所指向的结构体中指定。

    • EPOLL_CTL_MOD
      修改描述符fd上设定的事件,需用到由ev所指向的结构体中的信息。

    • EPOLL_CTL_DEL
      将描述符fd从 epoll 实例的 interest list 中移除,该操作忽略ev参数。

    上面我们多处提到了evev是指向结构体epoll_event的指针,该结构体的定义如下:

    struct epoll_event {
        uint32_t events;  // epoll 事件
        epoll_data data;  // 用户数据
    };

    结构体epoll_event中的data字段的类型为epoll_data,其定义以下:

    typedef union epoll_data {
        void *ptr;    // 用户自定义数据的指针
        int fd;       // 文件描述符
        uint32_t u32; // 32位整型
        uint64_t u64; // 64位整型
    } epoll_data_t;

    参数ev为文件描述符fd所做的设置如下:

    • 结构体epoll_event中的events字段是一个位掩码,它指定了 epoll 实例监控的事件集合
    • data字段是一个联合体,当fd就绪时,联合体的成员可用来指定传回给调用进程的信息

    就绪等待: epoll_wait

    系统调用epoll_wait返回 epoll 实例中处于就绪状态的文件描述符的信息。单个epoll_wait调用能返回多个就绪态文件描述符的信息,这也正是I/O多路复用的体现。

    #include <sys/epoll.h>
    int epoll_wait(int epfd, struct epoll_event *evlist, int maxevents, int timeout);
    • 参数evlist所指向的结构体数组中返回就绪状态文件描述符的信息。数据evlist的空间由调用者负责申请,所包含的元素个数在参数maxevents中指定。
    • 参数timeout指定epoll_wait的阻塞行为,例如timeout等于-1,调用将一直阻塞,走到 interest list 中的文件描述符上有事件产生。

    epoll_wait 调用成功后,返回数据evlist中的元素个数,即就绪的描述符个数。

    例子

    我们以编写一个 TCP 服务器为例子,说明 epoll 的用法,该 TCP 服务器打印出所有接收到的消息。
    我们先来看创建和绑定 TCP 监听套接字的函数。

    static int
    create_and_bind (char *port)
    {
        struct addrinfo hints;
        struct addrinfo *result, *rp;
        int s, sfd;
    
        memset (&hints, 0, sizeof (struct addrinfo));
        hints.ai_family = AF_UNSPEC;     // 支持 IPv4 和 IPv6
        hints.ai_socktype = SOCK_STREAM; // TCP socket
        hints.ai_flags = AI_PASSIVE;     // 监听套接字
    
        s = getaddrinfo (NULL, port, &hints, &result);
        if (s != 0)
        {
            fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (s));
            return -1;
        }
    
        for (rp = result; rp != NULL; rp = rp->ai_next)
        {
            sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
            if (sfd == -1)
                continue;
    
            s = bind (sfd, rp->ai_addr, rp->ai_addrlen);
            if (s == 0)
            {
                // 已成功绑定套接字
                break;
            }
    
            close (sfd);
        }
    
        if (rp == NULL)
        {
            fprintf (stderr, "Could not bind\n");
            return -1;
        }
    
        freeaddrinfo (result);
    
        return sfd;
    }

    create_and_bind接受port参数(表示监听的端口),其作用是创建并绑定监听套接字。
    getaddrinfo函数既可以用于IPv4,也可以用于IPv6,能够处理名字到地址以及服务到端口这两种转换,它返回addrinfo结构体数组的指针。关于getaddrinfo详细介绍,可以参考《UNIX网络编程》的有关描述。
    create_and_bind返回结构体addrinfo数组的指针(保存在reslut指针中)接下来,我们对result进行遍历,直到将监听套接字成功绑定为止。

    接下来,我们再来看将一个套接字设置为非阻塞套接字的函数。

    static int
    make_socket_non_blocking (int sfd)
    {
        int flags, s;
    
        flags = fcntl (sfd, F_GETFL, 0);
        if (flags == -1)
        {
            perror ("fcntl");
            return -1;
        }
    
        flags |= O_NONBLOCK;
        s = fcntl (sfd, F_SETFL, flags);
        if (s == -1)
        {
            perror ("fcntl");
            return -1;
        }
    
        return 0;
    }

    最后我们来看下main函数的实现。

    int
    main (int argc, char *argv[])
    {
        int sfd, s;
        int efd;
        struct epoll_event event;
        struct epoll_event *events;
    
        if (argc != 2)
        {
            fprintf (stderr, "Usage: %s [port]\n", argv[0]);
            exit (EXIT_FAILURE);
        }
    
        sfd = create_and_bind (argv[1]);
        if (sfd == -1)
            abort ();
    
        s = make_socket_non_blocking (sfd);
        if (s == -1)
            abort ();
    
        s = listen (sfd, SOMAXCONN);
        if (s == -1)
        {
            perror ("listen");
            abort ();
        }
    
        efd = epoll_create1 (0);
        if (efd == -1)
        {
            perror ("epoll_create");
            abort ();
        }
    
        event.data.fd = sfd;
        // ET 模式
        event.events = EPOLLIN | EPOLLET;
        s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);
        if (s == -1)
        {
            perror ("epoll_ctl");
            abort ();
        }
    
        // 用来存储epoll_wait返回的就绪文件描述符列表
        events = calloc (MAXEVENTS, sizeof event);
    
        // 主循环
        while (1)
        {
            int n, i;
    
            n = epoll_wait (efd, events, MAXEVENTS, -1);
            for (i = 0; i < n; i++)
            {
                if ((events[i].events & EPOLLERR) ||
                    (events[i].events & EPOLLHUP) ||
                    (!(events[i].events & EPOLLIN)))
                {
                    // 监测的文件描述符出错了
                    fprintf (stderr, "epoll error\n");
                    close (events[i].data.fd);
                    continue;
                }
    
                else if (sfd == events[i].data.fd)
                {
                    // 监听套接字就绪,表明有一个或者多个连接进来
                    while (1)
                    {
                        struct sockaddr in_addr;
                        socklen_t in_len;
                        int infd;
                        char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
    
                        in_len = sizeof in_addr;
                        infd = accept (sfd, &in_addr, &in_len);
                        if (infd == -1)
                        {
                            if ((errno == EAGAIN) ||
                                (errno == EWOULDBLOCK))
                            {
                                // 处理完所有的连接
                                break;
                            }
                            else
                            {
                                perror ("accept");
                                break;
                            }
                        }
    
                        s = getnameinfo (&in_addr, in_len,
                                         hbuf, sizeof hbuf,
                                         sbuf, sizeof sbuf,
                                         NI_NUMERICHOST | NI_NUMERICSERV);
                        if (s == 0)
                        {
                            printf("Accepted connection on descriptor %d "
                                           "(host=%s, port=%s)\n", infd, hbuf, sbuf);
                        }
    
                        // 设置已连接套接字为非阻塞,并且加入到 epoll 实例监测中
                        s = make_socket_non_blocking (infd);
                        if (s == -1)
                            abort ();
    
                        event.data.fd = infd;
                        // ET 模式
                        event.events = EPOLLIN | EPOLLET;
                        s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);
                        if (s == -1)
                        {
                            perror ("epoll_ctl");
                            abort ();
                        }
                    }
                    continue;
                }
                else
                {
                    // 已连接套接字可读,我们读取该套接字所有的数据并打印出来
                    // 由于使用了 ET 模式,我们必须将所有可读数据读取完毕
                    int done = 0;
    
                    while (1)
                    {
                        ssize_t count;
                        char buf[512];
    
                        count = read (events[i].data.fd, buf, sizeof buf);
                        if (count == -1)
                        {
                            // 如果 errno == EAGAIN,说明所有数据已读取完毕
                            // 如果 errno != EAGAIN,说明读取出错
                            if (errno != EAGAIN)
                            {
                                // 读取出错
                                perror ("read");
                                done = 1;
                            }
                            break;
                        }
                        else if (count == 0)
                        {
                            // 客户端断开了连接
                            done = 1;
                            break;
                        }
    
                        // 打印到标准输出
                        s = write (1, buf, count);
                        if (s == -1)
                        {
                            perror ("write");
                            abort ();
                        }
                    }
    
                    if (done)
                    {
                        printf ("Closed connection on descriptor %d\n",
                                events[i].data.fd);
    
                        // 关闭连接
                        close (events[i].data.fd);
                    }
                }
            }
        }
    
        free (events);
    
        close (sfd);
    
        return EXIT_SUCCESS;
    }

    main函数首先调用create_and_bind创建并绑定监听套接字,接下来调用make_socket_non_blocking设置监听套接字为非阻塞模式,并调用listen系统调用监听客户端的连接请求。
    接下来,我们创建了一个 epoll 实例,并将监听套接字加入到该 epoll 实例的 interest list,当监听套接字可读时,说明有新的客户端请求连接。
    在主循环中,我们调用epoll_wait等待就绪事件的发生。timeout参数设置为-1说明主线程会一直阻塞到事件就绪。这些就绪事件包括以下类型:

    • 客户端请求到达:当监听套接字可读时,说明一个或者多个客户端连接请求到达,我们设置新的已连接套接字为非阻塞模式并添加到 epoll 实例的 interest list 中。
    • 客户端数据可读:已连接套接字就绪时,说明客户端数据可读。我们使用read每次读出512字节的数据,直接所有的数据读取完毕。这是由于我们使用了 ET 模式,ET 模式对于数据可读只会通知一次。读出的数据通过write系统调用打印到标准输出。

    完整的程序可以在这里下载:epoll_example.c

    参考资料

    1. https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/
    2. Linux/UNIX 系统编程手册,Michael Kerrisk 著,郭光伟译,人民邮电出版社
    3. UNIX网络编程,卷1:套接字联网API,第3版,人民邮电出版社
    4. http://blog.lucode.net/linux/epoll-tutorial.html
    展开全文
  • 我选择了LED多路复用器作为一个电路,该电路很简单,不会妨碍实现我的主要目标的进度,但又足够复杂,比几个闪烁的LED更有趣和更具挑战性。 我以为我会将原型制作过程分为五个阶段: 第1阶段)取决于Arduino的实验...
  • IO多路复用和Reactor模式 IO多路复用和Reactor模式 1. Reactor和Preactor模式 2. Reactor模式中的主要角色 2.1. Reactor 2.2. Acceptor 2.3. Handler 3. 多线程下的Reactor 3.1. 多线程化的目的 ...
  • BIO&NIO&多路复用

    2018-06-26 15:12:05
    NIO 即 New IO,这个库是在 JDK1.4 中才引入。NIO 和B IO 有相同作用和目的,但实现方式不同,NIO 主要用到是块,所以 NIO 效率要比 BIO 高很
  • 通信三要素 1.消息来源,或发送方:消息来源是需要向其他人或者设备发送消息人或者电子设备。 2.目的地,或消息接收方:目的地地址接受并解释消息。 3.通道:包括提供消息... 分段消息有两个主要的优点: ...
  • 为了形成一个完整清晰的认识,将概念和关系梳理出来,把坑填平。 I/O多路复用 I/O多路复用主要解决传统I/O单线程阻塞的问题。...I/O多路复用的目的是为了更充分的利用CPU资源。 EPOLL(SELECT/POLL) Linux下I/O...
  • 带有ESP8266(D1 Mini)NMEA0183 WiFi多路复用器 从两个串行(RS232)输入读取NMEA0183消息,并将多路复用消息作为UDP广播转发到USB-Serial和WLAN。 多工器通过USB连接或通过DC-DC转换器以12伏电压供电。 ESP8266...
  • 计算机网络期末

    2020-12-22 20:32:21
    传输介质(填空)【问答】多路复用的主要目的是什么?常用的多路复用技术有哪些?三、物理层1.物理层提供的主要服务2.物理层解决的主要问题3.物理层的接口特性四、数据链路层1.CSMA/CD技术的原理是什么?2.三种CSMA3...
  • JDK1.4NIO有效解决了原有流式IO存在线程开销问题,在NIO中使用多线程,...NIO选择器采用了多路复用(Multiplexing)技术,可在一个选择器上处理多个套接字,通过获取读写通道来进行IO操作。由于网络带宽等原因
  • 目的是通过开发服务器-客户端体系结构并在套接字之间发送消息来了解TCP套接字编程和多路复用主要插座功能 :Python标准库提供了一个“套接字”模块。 套接字模块提供了底层网络接口。 它在客户端和服务器中具有8...
  • 这一本书的主要阅读的部分至网络层结束,其他暂时不看。 1.绪论 (1)TCP/IP模型 TCP/IP模型总共有5层,物理层,数据链路层,网络层,传输层,应用层。...源段进行多路复用目的端进行多路分解。 多路复用主要是指一个
  • HTTP 2.0是在SPDY(An experimental ...HTTP/2 的目的是通过支持请求与响应的多路复用来较少延迟,通过压缩HTTPS首部字段将协议开销降低,同时增加请求优先级和服务器端推送支持。 二进制分帧 在应用层与传输层...
  • 共享可用带宽的工作完全交给了统计复用的随机原理。只要任何一条链路的可用带宽远远大于平均的通信负载,大概每个人都会感满意。 <br/> 然而,时代已经发生了变化。企业的IP intranet和商业IP骨干网同样都要面临...
  • select, poll, epoll都是IO多路复用的机制,上文中提到的多路复用主要是以select为例,select和poll大同小异,因为select和poll的实现有明显的缺点,所以在Linux2.5.44中引入了新的处理大批量句柄的API——epoll,被...
  • 2018/8/23 第一次写博客,主要原因是...还有就是一些好代码和项目是通用,在很项目里面是可以套用,所以我写这个博客的目的一个在于记录一些解决开发问题方案,一个自然就是存储一些复制性很强,可复用...
  • 多路复用 连接 优先与安全 以下各段介绍了上面列举TCP基本操作 基本数据传输: 通过将一定数量八位字节打包成段,以便通过Internet系统传输,TCP能够在其用户之间每个方向上传输连续八位字节流。 ...
  • ffmepg (avformat.h里说明)

    千次阅读 2014-11-06 16:09:32
    二是多路复用的反转过程,将提供的数据写进指定容器格式。 其也有一个IO模块,支持多种协议访问数据(例如:file,tcp,http 等等 )。在使用lavf之前,我们需要调用 av_register_all()来注册所用已编译的muxers
  • 前导码的主要目的是促进接收,提供比特和数据包同步。 数据输入电路主要由存储元件和r=1/2的卷积编码器组成。 因此,输入位必须存储在临时存储器中,并按 61 位块进行分区。 然后卷积编码器将比特加倍,并在消息的...
  • 但是,它的主要缺点之一是点间干扰,这种干扰考虑了提出一种动机,即提出一种使用编码技术来区分波束的新方法,该波束将用于缓解这种干扰而无需频率复用。 这种方法利用正交码来识别波束,并允许使用每个波束的总...
  • 这里写自定义目录标题什么是计算机网络数据交换数据交换分类电路交换多路复用技术报文交换分组交换 什么是计算机网络数据交换 数据交换,是计算机网络实现数据通过网络核心,从源主机到达目的主机方法。 ...
  • NetSet是一款自动化安全增强工具,该工具的主要目的就是将很多复杂的操作以自动化的方式实现,并帮助用户保证网络流量的安全...实现了一种按需使用的终端多路复用器,其会话通过Tor路由,并通过自动安装和配置DNSCrypt
  • Java之NIO理解

    2017-04-23 12:40:26
    NIO是一种新IO模型(Recator模型),新主要体现在多路复用,事件驱动上 1、多路复用,一个线程可以处理多个socket请求,通过多个socket注册在一个select上面,然后不断调用select来获取被激活socket,即达到在...
  • 一.NIO产生背景 BIO,输入输出(原始) NIO(Not-blocking IO) 非阻塞IO模型  ... 服务端 多路复用技术 主要目的:提高程序性能,借鉴了一些先进思想 BIO和NIO都是同步IO二.必须明白几个概念 1)....

空空如也

空空如也

1 2 3 4 5 6
收藏数 111
精华内容 44
关键字:

多路复用的主要目的