Live555源码阅读笔记(四):groupsock 目录详解

简介: Live555源码阅读笔记(四):groupsock 目录详解

一、groupsock 目录介绍

2018122814580746.png

groupsock 目录总共有16个源码文件,编译后生成 libgroupsock.a,这个库中的类封装了网络接口和套接字,特别是“Groupsock”类封装了一个用于发送/或接收多播数据报的套接字。libgroupsock.a 作为live555的网络库,包含了TCP套接字和UDP套接字的创建以及收发数据,还实现了单播、多播,但代码量却很少,还是值得一看的。里面涉及很多基础网络编程知识,基础薄弱的同学阅读过后对网络编程会有新的了解。这篇文件旨在梳理这16个文件的逻辑关系和框架,帮助读者更好阅读源码。


二、阅读源码

阅读源码前,先看一下 Groupsock 的协作图,图中实线表示继承,虚线表示有该类的成员变量。可见,Groupsock 继承自 OutputSocket,OutputSocke 继承自 Socket,Socket 继承自 NetInterface。而 Groupsock 又有 GroupEId类、destRecord类、NetInterfaceTrafficStats类 的对象。其他的依此类推。对协作图有个大概了解后,下面看看几个主要的类以及主要的实现文件。

2018122814580746.png

1、GroupEId 类

GroupEId 类主要是对多播地址进行封装,用于创建一个多播地址(IP地址、端口号、源地址、TTL)

1.1、GroupEId 类的属性

private:
  struct in_addr fGroupAddress; // IP地址
  struct in_addr fSourceFilterAddress;// 源地址
  portNumBits fPortNum; // 端口号(使用网络字节序)
  u_int8_t fTTL; // Time To Live的缩写,表示IP包被路由器丢弃之前允许通过的最大网段数量

1.2、GroupEId 类的方法

GroupEId 类的方法主要分为为2部分,一个是构造 源无关 指定源 多播地址,另一个是获取ip地址、源地址、端口、TTL的,代码实现也很简单,可以看以下注释。

public:
  // 构造一个 源无关 或 指定源 的多播地址
  GroupEId(struct in_addr const& groupAddr,portNumBits portNum, u_int8_t ttl);
  GroupEId(struct in_addr const& groupAddr,struct in_addr const& sourceFilterAddr,
     portNumBits portNum);
  struct in_addr const& groupAddress() const { return fGroupAddress; }// 获取IP地址
  struct in_addr const& sourceFilterAddress() const {return fSourceFilterAddress;}//指定源地址
  Boolean isSSM() const;  // SSM(指定源组播)
  portNumBits portNum() const { return fPortNum; }// 获取端口号
  u_int8_t ttl() const { return fTTL; }
private:
  void init(struct in_addr const& groupAddr,struct in_addr const& sourceFilterAddr,
      portNumBits portNum,u_int8_t ttl);

2、NetAddress.hh 和 NetAddress.cpp

这两个文件主要实现了几个类用于对ip地址、端口号的封装,以及域名解析等,下面简单介绍各个类的功能:

2.1、NetAddress 类

NetAddress 类是对IP地址的封装,成员变量(属性) fLength 表示该IP地址的字节数,fData 是一个指向IP地址的指针。

成员函数(方法)中有三个构造函数用于不同情况创建对象,主要函数注释如下

NetAddress(u_int8_t const* data,unsigned length = 4);// 根据data的数据构造IP地址
NetAddress(unsigned length = 4); // 构造一个0.0.0.0的IP地址
NetAddress(NetAddress const& orig);// 根据另一个对象构造地址
NetAddress& operator=(NetAddress const& rightSide);// 赋值运算符函数
unsigned length() const { return fLength; }
u_int8_t const* data() const { return fData; } // always in network byte order

2.2、NetAddressList 类

NetAddressList 类主要用于域名解析,如果hostname是IP地址则返回一个元素的列表,如果是域名则返回该域名的所有IPV4地址的列表。

成员变量(属性) fNumAddresses 表示该IP地址列表的个数,fAddressArray 是一个指向IP地址列表的指针。

成员函数(方法)的各个实现看起来都挺简单的,没什么需要特别说明的,主要看懂构造函数里调用 gethostbyname 函数进行域名解析即可。

2.3、Port 类

对端口号进行封装。代码简单明了。

2.4、AddressPortLookupTable 类

AddressPortLookupTable 类是通过(地址1,地址2,端口)查找对象的通用表,内部是使用哈希表实现的,将“地址1,地址2,端口”合起来作为 key。

2.5、AddressString 类

AddressString 类可以接收 sockaddr_in、in_addr、netAddressBits 这三种类型的IP地址,并将该IP地址转为点分十进制的字符串(xxx.xxx.xxx.xxx),用来替换不是线程安全的 “inet_ntoa()”。

2.6、IsMulticastAddress 函数

IsMulticastAddress 函数用来判断是否为合法多播地址,多播路由器从不转发这个目的地址(224.0.0.0到224.0.0.255)的数据报。

3、NetInterface.hh 和 NetInterface.cpp

3.1、NetInterface 类

NetInterface 类是网络接口类,无提供接口方法,但有静态变量 DefaultUsageEnvironment,如果非 NULL,则用于每个新接口。

3.2、DirectedNetInterface 类

DirectedNetInterface类是定向网络接口类,提供了接口方法write、SourceAddrOKForRelaying。是 NetInterface类 的子类。

3.3、DirectedNetInterfaceSet 类

DirectedNetInterfaceSet 类是用于 DirectedNetInterface类 的定向网络接口表,内部实现是哈希表,用的 DirectedNetInterface 对象的地址作为 key。

3.4、Socket 类

Socket 类继承自 NetInterface类 ,是对套接字的封装,其构造函数根据端口号创建 udp 套接字,并保存到相关成员变量。由于构造函数是 protected 属性,不能直接实例化对象。

成员变量(属性) fSocketNum 记录创建成功的套接字,fPort 记录端口号,fEnv 记录使用环境相关的变量。

成员函数(方法)主要是创建套接字的,以及获取套接字、端口等,实现相对简单。

3.5、SocketLookupTable 类

SocketLookupTable 类是通过端口号查找 Socket类 对象的表,内部实现是哈希表。

3.6、NetInterfaceTrafficStats 类

NetInterfaceTrafficStats 类用于统计网络流量的。成员变量(属性) fTotNumPackets 表示总的包数,fTotNumBytes 表示总字节数。

4、OutputSocket 类

OutputSocket 类继承自 Socket类 ,默认情况下只用于发送数据,不会收到任何数据包。因为重写了父类的纯虚函数 handleRead ,所以 OutputSocket类 不是抽象类,且其构造函数是 public ,可以实例化。

成员属性(属性) fSourcePort 记录创建套接字时,内核指定的端口;fLastSentTTL 记录最后一次设置的TTL。

成员函数(方法)OutputSocket 创建 udp 套接字,端口号由内核指定。write 用于发送数据。

5、Groupsock 类

Groupsock 类用于发送和接收数据包。它最初是为发送/接收多播而设计的,但它也可以发送/接收单播。

方法:

public:
// 一、构造函数、析构函数
// 创建非特定源多播(组播)套接字:创建一个 UDP 套接字,并把本地ip地址加入到一个多播组中
Groupsock(UsageEnvironment& env,struct in_addr const& groupAddr,Port port,u_int8_t ttl);
// 创建特定源多播(组播)套接字
Groupsock(UsageEnvironment& env, struct in_addr const& groupAddr,
      struct in_addr const& sourceFilterAddr,Port port);// 特定源多播
virtual ~Groupsock();// 离开一个多播组
// 二、目标地址记录相关
// 记录使用单链表实现的,这里会传入下个头节点的地址,并返回新建的节点的地址
virtual destRecord* createNewDestRecord(struct in_addr const& addr, Port const& port, u_int8_t ttl, unsigned sessionId, destRecord* next);
// 修改“sessionId”对应的“destRecord”,sessionId不存在则添加一个新的“destRecord”。
void changeDestinationParameters(struct in_addr const& newDestAddr,
           Port newDestPort, int newDestTTL,unsigned sessionId = 0);
// 根据目标地址查找目标记录
unsigned lookupSessionIdFromDestination(struct sockaddr_in const& destAddrAndPort) const;
virtual void addDestination(struct in_addr const& addr, Port const& port, unsigned sessionId);// 向 fDests 添加目标记录
virtual void removeDestination(unsigned sessionId); // 从fDests链表删除指定 id 的目标
void removeAllDestinations(); // 清空目标记录
Boolean hasMultipleDestinations() const;// 有多个目标地址则返回true
// 三、获取多播地址相关参数
struct in_addr const& groupAddress() const ;
struct in_addr const& sourceFilterAddress() const; 
Boolean isSSM() const;
u_int8_t ttl() const;
// 四、套接字发送相关
void multicastSendOnly();// 没有使用
virtual Boolean output(UsageEnvironment& env, unsigned char* buffer, unsigned bufferSize,
       DirectedNetInterface* interfaceNotToFwdBackTo = NULL);
DirectedNetInterfaceSet& members() { return fMembers; } // // 没有使用
 五、套接字读取相关
virtual Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
        unsigned& bytesRead,struct sockaddr_in& fromAddressAndPort);// 重写了套接字读取函数

6、GroupsockHelper.hh 和 GroupsockHelper.cpp

这两个文件是一些网络接口的底层实现,包括创建套接字、发送/接收数据、设置发送/接收缓冲区、设置阻塞/非阻塞、加入/退出多播组 等。

// 创建一个 UDP 套接字,并设置相应属性
int setupDatagramSocket(UsageEnvironment& env, Port port)
// 创建 TCP 套接字,并设置 地址复用、端口复用
int setupStreamSocket(UsageEnvironment& env,Port port,Boolean makeNonBlocking,Boolean setKeepAlive)
// 从套接字读取数据
int readSocket(UsageEnvironment& env,int socket,unsigned char* buffer,unsigned bufferSize,struct sockaddr_in& fromAddress)
// 发送数据
Boolean writeSocket(UsageEnvironment& env,int socket, struct in_addr address, portNumBits portNum, unsigned char* buffer, unsigned bufferSize)
// “发送或接收”缓冲区相关
unsigned getSendBufferSize(UsageEnvironment& env, int socket);
unsigned getReceiveBufferSize(UsageEnvironment& env, int socket);
unsigned setSendBufferTo(UsageEnvironment& env,int socket, unsigned requestedSize);
unsigned setReceiveBufferTo(UsageEnvironment& env,int socket, unsigned requestedSize);
unsigned increaseSendBufferTo(UsageEnvironment& env,int socket, unsigned requestedSize);
unsigned increaseReceiveBufferTo(UsageEnvironment& env,int socket,unsigned requestedSize);
// 设置非阻塞
Boolean makeSocketNonBlocking(int sock)
// 设置阻塞
Boolean makeSocketBlocking(int sock, unsigned writeTimeoutInMilliseconds)
// 将 socket 加入多播组
Boolean socketJoinGroup(UsageEnvironment& env,int socket,netAddressBits groupAddress)
// 将 socket 退出多播组
Boolean socketLeaveGroup(UsageEnvironment&, int socket,netAddressBits groupAddress)
// 将 socket 加入“特定源”多播组 - SSM ( Source-Specific Multicast,特定源组播)
Boolean socketJoinGroupSSM(UsageEnvironment& env, int socket,netAddressBits groupAddress,
         netAddressBits sourceFilterAddr) 
// 将 socket 退出“特定源”多播组
Boolean socketLeaveGroupSSM(UsageEnvironment& /*env*/, int socket,netAddressBits groupAddress,netAddressBits sourceFilterAddr) 
目录
相关文章
|
视频直播
视频直播源码技术知识分享:连麦功能(一)
我们开发视频直播平台就要去了解视频直播开发相关功能知识,这对我们开发平台有着重要的作用,连麦技术就是视频直播源码重要的技术功能之一,每一个功能技术都有自己的用武之地
视频直播源码技术知识分享:连麦功能(一)
|
视频直播
详解!视频直播源码平台搭建开发:录制功能
视频直播源码平台的录制功能能够为用户提供更多方便、灵活性,同时也增加了直播内容的传播和价值,这也使录制功能成为布谷科技视频直播源码平台的必备功能之一。
详解!视频直播源码平台搭建开发:录制功能
|
视频直播 定位技术 UED
海外视频直播源码技术视频直播间的搭建
大家听到这里是不是感觉这个源码平台非常的熟悉,没错,这个源码平台就海外视频直播源码平台,而我说的这个房间就是视频直播间,主持人就是视频直播间内的主播,今天我就为大家分享海外视频直播源码技术视频直播间的搭建。
海外视频直播源码技术视频直播间的搭建
|
存储 调度
Live555源码阅读笔记(三):BasicUsageEnvironment 目录详解-BasicTaskScheduler、DelayQueue、HandlerSet
Live555源码阅读笔记(三):BasicUsageEnvironment 目录详解-BasicTaskScheduler、DelayQueue、HandlerSet
174 0
Live555源码阅读笔记(三):BasicUsageEnvironment 目录详解-BasicTaskScheduler、DelayQueue、HandlerSet
|
调度 C++
Live555源码阅读笔记(二):UsageEnvironment 目录详解
Live555源码阅读笔记(二):UsageEnvironment 目录详解
155 0
Live555源码阅读笔记(二):UsageEnvironment 目录详解
|
编解码 数据建模 Unix
Live555源码阅读笔记(一):源码介绍文档 及 源码目录结构
Live555源码阅读笔记(一):源码介绍文档 及 源码目录结构
408 0
Live555源码阅读笔记(一):源码介绍文档 及 源码目录结构
|
视频直播
新人主播如何赚钱,3点告诉你视频直播源码的变现方式
全民直播的时代已经到来抓住,绝大多数人是发现了直播市场的红利期,想要分一杯羹,作为新人主播如何通过视频直播源码的功能来赚钱,首先要了解市场需求,明确自己的优势,凸显自己的竞争力。
新人主播如何赚钱,3点告诉你视频直播源码的变现方式
|
存储 缓存 NoSQL
开发视频直播系统,视频直播系统源码是核心技术
了解视频直播行业的朋友应该清楚,对于开发视频直播系统而言,视频直播系统源码是真正的核心技术
开发视频直播系统,视频直播系统源码是核心技术
|
搜索推荐 视频直播
视频直播源码提高用户满意度必须要具有的特性
目前直播app应用开发市场已进入快速发展时期,不仅越来越多的直播app应用陆续投放到应用市场中,同时用户对于手机直播app应用软件的要求也越来越高。随着年轻用户群体的个性化需求提升,如何提高用户满意度,便成为了视频直播源码的开发最为关键的问题之一。  
视频直播源码提高用户满意度必须要具有的特性
|
视频直播
直播系统的顶梁柱:视频直播源码中的礼物功能
我们了解的直播系统功能是十分的实用且丰富的,一般来说,视频直播源码自带的功能有:直播功能、私信功能、邀请奖励、财务管理功能、短视频功能、直播PK功能、多种礼物功能、分享功能、拉黑功能、带货商城功能、家族功能、标签功能、评论功能等等实质性的功能,今天就针对礼物功能来做一下详细的介绍。
直播系统的顶梁柱:视频直播源码中的礼物功能