zoukankan      html  css  js  c++  java
  • 27 GroupSock概述(一)——live555源码阅读(四)网络

    27 GroupSock概述(一)——live555源码阅读(四)网络

    本文由乌合之众 lym瞎编,欢迎转载 blog.cnblogs.net/oloroso
    本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso

    简介

    group是组/群的意思,socket是网络接口的代名词了。这个部分很庞大,主要是与网络相关的。而live555的网络模块很多都涉及到组播的概念。
    作为一个跨平台的流媒体服务库,live555对网络的封装很全面,值得一看。

    1.网络通用数据类型定义

    因为live555跨平台的特点,需要定义一些在数据类型来适应各个平台环境。
    这写代码在live555sourcecontrolgroupsockincludeNetCommon.h文件中

    #if defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_WCE)
    /* Windows */
    #if defined(WINNT) || defined(_WINNT) || defined(__BORLANDC__) || defined(__MINGW32__) || defined(_WIN32_WCE)
    #define _MSWSOCK_
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #endif
    #include <windows.h>
    #include <string.h>
    
    #define closeSocket closesocket     //关闭socket函数
    #define EWOULDBLOCK WSAEWOULDBLOCK  //10035L 可能会被阻塞
    #define EINPROGRESS WSAEWOULDBLOCK  //10035L 操作正在进行
    #define EAGAIN      WSAEWOULDBLOCK  //10035L 再试一次
    #define EINTR       WSAEINTR        //10004L 中断
    
    #if defined(_WIN32_WCE)
    #define NO_STRSTREAM 1
    #endif
    
    /* Definitions of size-specific types: 定义特定大小的类型*/
    typedef __int64 int64_t;
    typedef unsigned __int64 u_int64_t;
    typedef unsigned u_int32_t;
    typedef unsigned short u_int16_t;
    typedef unsigned char u_int8_t;
    // For "uintptr_t" and "intptr_t", we assume that if they're not already defined, then this must be
    // “uintptr_t”和“intptr_t”,我们认为如果他们不是已经定义,那么这一定是
    // an old, 32-bit version of Windows: 一个老的,32位版本的Windows:
    #if !defined(_MSC_STDINT_H_) && !defined(_UINTPTR_T_DEFINED) && !defined(_UINTPTR_T_DECLARED) && !defined(_UINTPTR_T)
    typedef unsigned uintptr_t;
    #endif
    #if !defined(_MSC_STDINT_H_) && !defined(_INTPTR_T_DEFINED) && !defined(_INTPTR_T_DECLARED) && !defined(_INTPTR_T)
    typedef int intptr_t;
    #endif
    
    #elif defined(VXWORKS)
    /* VxWorks */
    #include <time.h>
    #include <timers.h>
    #include <sys/times.h>
    #include <sockLib.h>
    #include <hostLib.h>
    #include <resolvLib.h>
    #include <ioLib.h>
    
    typedef unsigned int u_int32_t;
    typedef unsigned short u_int16_t;
    typedef unsigned char u_int8_t;
    
    #else
    /* Unix */
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/time.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <strings.h>
    #include <ctype.h>
    #include <stdint.h>
    #if defined(_QNX4)
    #include <sys/select.h>
    #include <unix.h>
    #endif
    
    #define closeSocket close
    
    #ifdef SOLARIS
    #define u_int64_t uint64_t
    #define u_int32_t uint32_t
    #define u_int16_t uint16_t
    #define u_int8_t uint8_t
    #endif
    #endif
    
    #ifndef SOCKLEN_T
    #define SOCKLEN_T int
    #endif
    

    2.Tunnel隧道封装

    这里代码里面已经注释得很明白了。这个首先需要了解以下什么是Tunnel(隧道)。(简单的说,它就像是披着羊皮的狼)

    tunnel中文译为隧道。网络隧道(Tunnelling)技术是个关键技术。网络隧道技术指的是利用一种网络协议来传输另一种网络协议,它主要利用网络隧道协议来实现这种功能。网络隧道技术涉及了三种网络协议,即网络隧道协议、隧道协议下面的承载协议和隧道协议所承载的被承载协议。

    这里实现的TunnelEncapsulationTrailer类是一个很特殊的类,它不应该被用来创建对象。
    对于这一部分,这里先不多说,先看后面的。
    其定义在live555sourcecontrolgroupsockincludeTunnelEncaps.hh文件中

    typedef u_int16_t Cookie;
    /* cookie(储存在用户本地终端上的数据)
    Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而
    储存在用户本地终端上的数据(通常经过加密)。定义于RFC2109和2965都已废弃,最新规范是RFC6265 。
    */
    
    /*tunnel中文译为隧道。网络隧道(Tunnelling)技术是个关键技术。网络隧道技术指的是利用一种网络协议来传输另一种网络协议,它主要利用网络隧道协议来实现这种功能。网络隧道技术涉及了三种网络协议,即网络隧道协议、隧道协议下面的承载协议和隧道协议所承载的被承载协议。
    */
    
    // 这个类很有意思,它内部并无数据成员,其函数成员的返回都是以this为基准进行偏移
    // 后,转换这个偏移后的地址为相应的指针类型,再取指针指向内存的内容。
    // 所以这个类并不会用来创建对象,而是作为一种类型来使用。可能诸如以下代码
    // unsigned long long t= 0x1239874560864216L;
    //  cout << ((TunnelEncapsulationTrailer*)&t)->address() << endl;
    //  cout << 0x12398745 << endl;
    
    class TunnelEncapsulationTrailer {
        // The trailer is layed out as follows:
        // bytes 0-1:   source 'cookie'         源Cookie
        // bytes 2-3:   destination 'cookie'    目的Cookie
        // bytes 4-7:   address                 地址
        // bytes 8-9:   port                    端口
        // byte 10:     ttl                     TTL
        // byte 11:     command                 命令
    
            // Optionally, there may also be a 4-byte 'auxilliary address'
            // 随意,也可能有一个4字节的"辅助地址"
            // (e.g., for 'source-specific multicast' preceding this)
            // (例如,“特定源组播”在此之前)
            // bytes -4 through -1: auxilliary address
            // -4到-1字节(this之前4个字节),辅助地址
    
        public:
        Cookie& srcCookie()
            { return *(Cookie*)byteOffset(0); }
        Cookie& dstCookie()
            { return *(Cookie*)byteOffset(2); }
        u_int32_t& address()
            { return *(u_int32_t*)byteOffset(4); }
        Port& port()
            { return *(Port*)byteOffset(8); }
        u_int8_t& ttl()
            { return *(u_int8_t*)byteOffset(10); }
        u_int8_t& command()
            { return *(u_int8_t*)byteOffset(11); }
    
            u_int32_t& auxAddress()
                    { return *(u_int32_t*)byteOffset(-4); }
    
        private:    
        //取this偏移charIndex
        inline char* byteOffset(int charIndex)
            { return ((char*)this) + charIndex; }
    };
    
    const unsigned TunnelEncapsulationTrailerSize = 12; // bytes隧道封装拖车尺寸
    const unsigned TunnelEncapsulationTrailerAuxSize = 4; // bytes辅助的尺寸
    const unsigned TunnelEncapsulationTrailerMaxSize    //最大尺寸
        = TunnelEncapsulationTrailerSize + TunnelEncapsulationTrailerAuxSize;
    
    // Command codes:命令码
    // 0: unused
    const u_int8_t TunnelDataCmd = 1;           //隧道的数据命令
    const u_int8_t TunnelJoinGroupCmd = 2;      //隧道连接组命令
    const u_int8_t TunnelLeaveGroupCmd = 3;     //隧道离开组命令
    const u_int8_t TunnelTearDownCmd = 4;       //隧道拆除命令
    const u_int8_t TunnelProbeCmd = 5;          //隧道探针命令
    const u_int8_t TunnelProbeAckCmd = 6;       //隧道探针ACK命令
    const u_int8_t TunnelProbeNackCmd = 7;      //隧道探针NACK命令
    const u_int8_t TunnelJoinRTPGroupCmd = 8;   //隧道加入RTP组命令
    const u_int8_t TunnelLeaveRTPGroupCmd = 9;  //隧道离开RTP组命令
    
    // 0x0A through 0x10: currently unused.0x0a到0x10:目前未使用
    // a flag, not a cmd code一个标识,不是命令码。隧道扩展标识
    const u_int8_t TunnelExtensionFlag = 0x80;  //bits:1000 0000
    
    const u_int8_t TunnelDataAuxCmd         //隧道数据辅助命令
        = (TunnelExtensionFlag|TunnelDataCmd);
    const u_int8_t TunnelJoinGroupAuxCmd    //隧道连接组辅助命令
        = (TunnelExtensionFlag|TunnelJoinGroupCmd);
    const u_int8_t TunnelLeaveGroupAuxCmd   //隧道离开组辅助命令
        = (TunnelExtensionFlag|TunnelLeaveGroupCmd);
    // Note: the TearDown, Probe, ProbeAck, ProbeNack cmds have no Aux version
    // 注意:TearDown(拆除),Probe(探针),ProbeAck(Ack探针),ProbeNack(NACK探针)没有辅助版命令
    // 0x84 through 0x87: currently unused.
    const u_int8_t TunnelJoinRTPGroupAuxCmd //隧道加入RTP组辅助命令
        = (TunnelExtensionFlag|TunnelJoinRTPGroupCmd);
    const u_int8_t TunnelLeaveRTPGroupAuxCmd//隧道离开RTP组辅助命令
        = (TunnelExtensionFlag|TunnelLeaveRTPGroupCmd);
    // 0x8A through 0xFF: currently unused
        //判断参数cmd是否是辅助命令
    inline Boolean TunnelIsAuxCmd(u_int8_t cmd) {
      return (cmd&TunnelExtensionFlag) != 0;
    }
    
  • 相关阅读:
    NSRunLoop的利用
    快速排序算法
    WebViewJavascriptBridge的暂时理解
    非常喜欢的一期《晓松奇谈》
    字符串正则替换replace第二个参数是函数的问题
    Model模型和Module模块的区别
    jQuery的extend方法的深层拷贝
    正则表达式学习记录
    select2初始化默认值
    增进编程语言学习速度的小技巧
  • 原文地址:https://www.cnblogs.com/oloroso/p/4613329.html
Copyright © 2011-2022 走看看