前面我们看过了软总线的发现,组网,认证处理,现在我们看一下软总线的传输处理。

创建会话

创建会话的接口如下:

SoftBusServer::CreateSessionServer(const char *pkgName, const char *sessionName)

其直接调用了函数TransCreateSessionServer,其源码如下:

int32_t TransCreateSessionServer(const char *pkgName, const char *sessionName)
{if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX) ||!IsValidString(sessionName, SESSION_NAME_SIZE_MAX)) {return SOFTBUS_INVALID_PARAM;}if (CheckTransPermission(sessionName, pkgName, ACTION_CREATE) < SOFTBUS_OK) {LOG_ERR("TransCreateSessionServer no permission!\n");return SOFTBUS_PERMISSION_DENIED;}SessionServer *newNode = (SessionServer *)SoftBusCalloc(sizeof(SessionServer));if (newNode == NULL) {return SOFTBUS_ERR;}if (strcpy_s(newNode->pkgName, sizeof(newNode->pkgName), pkgName) != EOK) {SoftBusFree(newNode);return SOFTBUS_ERR;}if (strcpy_s(newNode->sessionName, sizeof(newNode->sessionName), sessionName) != EOK) {SoftBusFree(newNode);return SOFTBUS_ERR;}newNode->type = SEC_TYPE_CIPHERTEXT;int ret = TransSessionServerAddItem(newNode);if (ret != SOFTBUS_OK) {SoftBusFree(newNode);if (ret == SOFTBUS_SERVER_NAME_REPEATED) {LOG_INFO("SessionServer is already created [%s]", sessionName);return SOFTBUS_SERVER_NAME_REPEATED;}return ret;}LOG_INFO("CreateSessionServer OK, pkg name: [%s], session name: [%s]", pkgName, sessionName);return SOFTBUS_OK;
}

该函数首先创建了一个SessionServer节点,然后将其加入到g_sessionServerList列表中。

打开会话

打开会话的接口如下:

int32_t SoftBusServer::OpenSession(const char *mySessionName, const char *peerSessionName,const char *peerDeviceId, const char *groupId, int32_t flags)

其调用了函数TransOpenSession,源码如下:

int32_t TransOpenSession(const char *mySessionName, const char *peerSessionName,const char *peerDeviceId, const char *groupId, int32_t flags)
{LOG_INFO("trans server opensession.");if (!IsValidString(mySessionName, SESSION_NAME_SIZE_MAX) ||!IsValidString(peerSessionName, SESSION_NAME_SIZE_MAX) ||!IsValidString(peerDeviceId, DEVICE_ID_SIZE_MAX) ||!IsValidString(groupId, GROUP_ID_SIZE_MAX)) {return INVALID_CHANNEL_ID;}char pkgName[PKG_NAME_SIZE_MAX];if (TransGetPkgNameBySessionName(mySessionName, pkgName, PKG_NAME_SIZE_MAX) != SOFTBUS_OK) {LOG_ERR("TransGetPkgNameBySessionName failed");return SOFTBUS_ERR;}if (CheckTransPermission(mySessionName, pkgName, ACTION_OPEN) < SOFTBUS_OK) {LOG_ERR("TransOpenSession no permission!");return SOFTBUS_PERMISSION_DENIED;}if (!TransSessionServerIsExist(mySessionName)) {LOG_ERR("session server invalid");return INVALID_CHANNEL_ID;}return TransOpenChannel(mySessionName, peerSessionName, peerDeviceId, groupId, flags);
}

该函数对入参进行校验之后,便调用TransOpenChannel进行处理,该函数源码如下:

int32_t TransOpenChannel(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId,const char *groupId, int32_t flags)
{int32_t channelId = INVALID_CHANNEL_ID;if (!IsValidString(mySessionName, SESSION_NAME_SIZE_MAX) ||!IsValidString(peerSessionName, SESSION_NAME_SIZE_MAX) ||!IsValidString(peerDeviceId, DEVICE_ID_SIZE_MAX) ||!IsValidString(groupId, GROUP_ID_SIZE_MAX)) {return channelId;}ConnectOption connOpt = {0};AppInfo *appInfo = GetAppInfo(mySessionName, peerSessionName, peerDeviceId, groupId, flags);if (appInfo == NULL) {LOG_ERR("get app info err");return channelId;}int type = TransGetChannelType();switch (type) {case CHANNEL_TYPE_PROXY:if (GetConnectOptionBr(peerDeviceId, &connOpt) != SOFTBUS_OK) {LOG_ERR("get connection opt err");break;}if (TransProxyOpenProxyChannel(appInfo, &connOpt, &channelId) != SOFTBUS_OK) {LOG_ERR("open proxy channel err");channelId = INVALID_CHANNEL_ID;}break;
#ifndef SOFTBUS_WATCHcase CHANNEL_TYPE_TCP_DIRECT:if (GetConnectOptionTcp(peerDeviceId, &connOpt) != SOFTBUS_OK) {LOG_ERR("get connection opt err");break;}if (TransOpenTcpDirectChannel(appInfo, &connOpt, &channelId) != SOFTBUS_OK) {LOG_ERR("open direct channel err");channelId = INVALID_CHANNEL_ID;}break;
#endifdefault:break;}SoftBusFree(appInfo);return channelId;
}

该函数分为2步:

  1. 调用GetAppInfo创建了一个新的appInfo
  2. 然后根据ChannelType的类型,选择对应的处理。

第2步以CHANNEL_TYPE_TCP_DIRECT为例,该场景下:

  1. 调用GetConnectOptionTcp获取对端的IP地址和Port号,并保存在connOpt中。
  2. 调用TransOpenTcpDirectChannel进行处理。

TransOpenTcpDirectChannel的源码如下:

int32_t TransOpenTcpDirectChannel(AppInfo *appInfo, const ConnectOption *connInfo, int *fd)
{if (appInfo == NULL || connInfo == NULL || fd == NULL) {LOG_ERR("param is invalid.");return SOFTBUS_INVALID_PARAM;}char *ip = (char*)connInfo->info.ipOption.ip;int sessionPort = connInfo->info.ipOption.port;appInfo->routeType = WIFI_STA;SessionConn *newConn = (SessionConn*)SoftBusMalloc(sizeof(SessionConn));if (newConn == NULL) {LOG_ERR("Malloc err.");return SOFTBUS_ERR;}if (memcpy_s(&newConn->appInfo, sizeof(AppInfo), appInfo, sizeof(AppInfo)) != EOK) {SoftBusFree(newConn);LOG_ERR("Memcpy ip err.");return SOFTBUS_ERR;}newConn->appInfo.fd = -1;newConn->serverSide = false;newConn->channelId = INVALID_CHANNEL_ID;if (strcpy_s(newConn->appInfo.peerData.ip, IP_LEN, ip) != EOK) {SoftBusFree(newConn);LOG_ERR("strcpy_s err.");return SOFTBUS_ERR;}newConn->appInfo.peerData.port = sessionPort;newConn->status = TCP_DIRECT_CHANNEL_STATUS_HANDSHAKING;newConn->timeout = 0;if (InitTdcInfo(newConn) != SOFTBUS_OK) {SoftBusFree(newConn);return SOFTBUS_ERR;}*fd = OpenConnTcp(appInfo, connInfo);if (*fd <= 0) {TransCloseDirectChannel(newConn->channelId);SoftBusFree(newConn);LOG_ERR("OpenConnTcp err.");return SOFTBUS_ERR;}newConn->appInfo.fd = *fd;newConn->channelId = *fd;if (AddTrigger(DIRECT_CHANNEL_SERVER, newConn->appInfo.fd, RW_TRIGGER) != SOFTBUS_OK) {TransCloseDirectChannel(newConn->channelId);SoftBusFree(newConn);LOG_ERR("AddTrigger failed");return SOFTBUS_ERR;}return SOFTBUS_OK;
}

该函数分为4步:

  1. 创建了一个SessionConn节点,并对其进行赋值操作。
  2. 调用InitTdcInfo对创建的SessionConn节点进行初始化。
  3. 调用OpenConnTcp,根据对端的IP和端口号建议Socket连接
  4. 调用AddTrigger将socket描述符添加到g_listenerList里面DIRECT_CHANNEL_SERVER模块对应的的info中。

这里整体代码比较简单,因此不展开。

软总线源码分析8:传输模块相关推荐

  1. FFmpeg简述,源码分析,录制/压缩/水印/剪切/旋转/滤镜/美颜/上传视频等(CPU软编码和解码)

    > ffmpeg源码分析 ffmpeg源码简析(一)结构总览- https://blog.csdn.net/Louis_815/article/details/79621056 FFmpeg的库 ...

  2. v66.07 鸿蒙内核源码分析(根文件系统) | 谁先挂到/谁就是根总 | 百篇博客分析OpenHarmony源码

    季康子问政于孔子.孔子对曰:"政者,正也.子帅以正,孰敢不正?" <论语>:颜渊篇 百篇博客系列篇.本篇为: v66.xx 鸿蒙内核源码分析(根文件系统) | 谁先挂到 ...

  3. 实际测试例子+源码分析的方式解剖MyBatis缓存的概念

    前言: 前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ 欢迎工作一到五年的Java工程师朋友们加入Java架构开发:79 ...

  4. Android 源码分析之 EventBus 的源码解析

    1.EventBus 的使用 1.1 EventBus 简介 EventBus 是一款用于 Android 的事件发布-订阅总线,由 GreenRobot 开发,Gihub 地址是:EventBus. ...

  5. 通过源码分析MyBatis的缓存

    前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ MyBatis缓存介绍 首先看一段wiki上关于MyBatis缓存的介绍 ...

  6. 【深入浅出MyBatis系列十一】缓存源码分析

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 深入浅出MyBatis系列 [深入浅出MyBatis系列一]MyBatis入门 [深入浅出MyBatis系列二]配置 ...

  7. 【作者面对面问答】包邮送《Redis 5设计与源码分析》5本

    墨墨导读:本文节选自<Redis 5设计与源码分析>,主要为读者分析Redis高性能内幕,重点从源码层次讲解了Redis事件模型,网络IO事件重在使用IO复用模型,时间事件重在限制最大执行 ...

  8. android源码分析

    01_Android系统概述 02_Android系统的开发综述 03_Android的Linux内核与驱动程序 04_Android的底层库和程序 05_Android的JAVA虚拟机和JAVA环境 ...

  9. MyBatis学习笔记-源码分析篇

    引言 SQL 语句的执行涉及多个组件,其中比较重要的是 Executor. StatementHandler. ParameterHandler 和 ResultSetHandler. Executo ...

最新文章

  1. 线性回归、逻辑回归、损失函数
  2. 单机、集群与分布式的概念(转)
  3. 十六、python沉淀之路--迭代器
  4. 更新wpscan_wpscan扫描工具
  5. android执行命令行取得结果,Android调用shell脚本并取得输出
  6. 电磁冷坩埚行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  7. Dubbo即将毕业,晋升为Apache顶级项目?
  8. redhat as4 上安装 MySQL5
  9. 清除eclipse当前登录的SVN账户
  10. jQuery 的 ajax 请求方法
  11. CMFCMenuBar 的另类动态修改
  12. 从这三个维度说一说,如何做一名具有产品思维的UI设计师?
  13. 日期转换和日历的使用方法
  14. 定点 浮点 神经网络 量化_定点量化
  15. 感恩工作平台心得体会_感恩工作心得体会
  16. 苹果审核Metadata Rejected解决
  17. 三十.什么是vm和vc?
  18. cad动态块制作翻转_CAD创建动态块实例教程:旋转参数和动作的应用 - CAD自学网...
  19. Python 将MP3音频文件转换成MIDI乐谱文件
  20. 360T7路由器进行WiFi无线中继教程

热门文章

  1. 查询一年1、1-2月、1-3~一直到1-12月
  2. 数据结构-图-知识点总结
  3. 三种css垂直居中方案
  4. 永不言弃,希望就在前方
  5. 韦东山 android 淘宝,韦东山-android音频子系统中audio_policy.conf的usb声卡理解 - 百问网嵌入式问答社区...
  6. 宝塔免费ssl证书是什么
  7. 历届试题 矩阵翻硬币 蓝桥杯 大数开方 大数相乘
  8. python实现K-means多维数据聚类代码
  9. 在商城项目开发中怎么保证促销商品不会超卖
  10. 计算机应用程序无响应,Win7系统运行Word文档提示“应用程序没有响应”怎么办...