借用Licdoe的代码来分析下ICE的实现
首先licode 用了两套ice库,不知道为啥,nicer 和Libnicer ,但感觉比较偏重于libnicer,所有着重以Libnice为主
二者分家的地方在 DtlsTransport类的构造函数中

licode 的底层传输采用了dtls的协议,这块不着重分析,知道就可以了。
下面开始
第一个问题:
ICE的线程模型
ICE代码还没看,但从Licode的应用来看,线程是由外面给出的,这个从ICE的使用说明可以看到:

具体使用情况也是需要传进一个Loop,

第二个问题:
ICE的底层传输用的那一套
现在看来,ICE的底层库,应该是本身自带的Udp库
第三个问题: ICE是数据封装层,它和应用层的关系如何
ICE的上层应用是dtls ,证据如下

listerner被设置为了dtls的实例,
dtl也是个中间层,主要负责数据加密解密,如果输在从上层传过来,dtls会直接给ice,代码如下



当有数据从ICE上来是,会首先给dtls
void DtlsTransport::onIceData(packetPtr packet) {
if (!running_) {
return;
}
int len = packet->length;
char *data = packet->data;
unsigned int component_id = packet->comp;
int length = len;
SrtpChannel *srtp = srtp_.get();
if (DtlsTransport::isDtlsPacket(data, len)) {
ELOG_DEBUG("%s message: Received DTLS message, transportName: %s, componentId: %u",
toLog(), transport_name.c_str(), component_id);
if (component_id == 1) {
std::lock_guard<std::mutex> guard(dtls_mutex);
dtlsRtp->read(reinterpret_cast<unsigned char*>(data), len);
} else {
std::lock_guard<std::mutex> guard(dtls_mutex);
dtlsRtcp->read(reinterpret_cast<unsigned char*>(data), len);
}
return;
} else if (this->getTransportState() == TRANSPORT_READY) {
std::shared_ptr<DataPacket> unprotect_packet = std::make_shared<DataPacket>(component_id,
data, len, VIDEO_PACKET, packet->received_time_ms);
if (dtlsRtcp != NULL && component_id == 2) {
srtp = srtcp_.get();
}
if (srtp != NULL) {
RtcpHeader *chead = reinterpret_cast<RtcpHeader*>(unprotect_packet->data);
if (chead->isRtcp()) {
if (srtp->unprotectRtcp(unprotect_packet->data, &unprotect_packet->length) < 0) {
return;
}
} else {
if (srtp->unprotectRtp(unprotect_packet->data, &unprotect_packet->length) < 0) {
return;
}
}
} else {
return;
}
if (length <= 0) {
return;
}
if (auto listener = getTransportListener().lock()) {
listener->onTransportData(unprotect_packet, this);
}
}
}
这段代码首先判断是否属于dtls的包,如果是,那么处理dtls,奇怪为啥这里分为rtp和rtcp两个动作

如果不是dtls的包,那么首先解密rtp

然后把解析出来的数据,传给listener

这个listener是什么意思呢?

这个listerner是webrtcconnection的实例,这样数据就流入到了webrtc里面

可以看到数据进入到了media_stream里面
这样这个流程就结束了
所以,licode里的协议栈顺序为:
UDP---ICE---DTLS----SRTP----RTP
这样的
版权声明:本文为ddr77原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。