tcp_session_manager.c代码分析中篇
本篇主要分析tcp_session_manager.c中出现的函数
一、相关链接和本篇代码相关的一些背景知识和该文件的上一部分代码详解:
- tcp_socket机制详解
- 互斥锁和消息队列详解
- tcp_session详解
- tcp_session_manager.c代码分析上篇
static bool AssignValue2Session(TcpSession *session, cJSON *receiveObj)
//标记值转换到session
{
if (receiveObj == NULL) {
return false;
//检查参数
}
char *recvBus = GetJsonString(receiveObj, "BUS_NAME");
//通过参数获取jsonstring
if (recvBus == NULL) {
return false;
//检查上一步是否成功获取
}
if (strncpy_s(session->sessionName, NAME_LENGTH, recvBus, strlen(recvBus)) != 0) {
return false;
}
char *sessionKeyEncoded = GetJsonString(receiveObj, "SESSION_KEY");
//获取sessionkey的json.string值
if (sessionKeyEncoded == NULL) {
return false;//检查是否获取成功
}
size_t olen = 0;
int ret = mbedtls_base64_decode((unsigned char *)session->sessionKey, SESSION_KEY_LENGTH,
&olen, (unsigned char *)sessionKeyEncoded, strlen(sessionKeyEncoded));
//基于base64进行编码
if (ret != 0) {
SOFTBUS_PRINT("[TRANS] AssignValue2Session mbedtls_base64_decode error: %d\n", ret);
return false;
//用来检查是否编码成功
}
SOFTBUS_PRINT("[TRANS] AssignValue2Session busname=%s, fd=%d\n", session->sessionName, session->fd);
return true;
}
static bool ResponseToClient(TcpSession *session)//客户端响应函数
{
cJSON *jsonObj = cJSON_CreateObject();
if (jsonObj == NULL) {
return false;
}
GetReplyMsg(jsonObj, session);//接受回复的消息
char *msg = cJSON_PrintUnformatted(jsonObj);
//将jsonObj转换为字符串数据
if (msg == NULL) {
cJSON_Delete(jsonObj);
return false;、
//检查是否转换成功
}
int bufLen = 0;
unsigned char *buf = PackBytes(msg, &bufLen);
//打包数据
if (buf == NULL) {
SOFTBUS_PRINT("[TRANS] ResponseToClient PackBytes fail\n");
free(msg);
cJSON_Delete(jsonObj);
return false;
}
int dataLen = TcpSendData(session->fd, (char*)buf, bufLen, 0);
//发送数据到tcp连接的另一端,datalen的值为发送的数据大小
free(msg);
cJSON_Delete(jsonObj);
free(buf);
if (dataLen fd, data, AUTH_PACKET_HEAD_SIZE, 0);
//size为接收信息的数据大小
if (size != AUTH_PACKET_HEAD_SIZE) {
return false;
//检查接受的数据大小是否和用户数据包大小相同
}
int identifier = GetIntFromBuf(data, 0); 用来将data中内容以offset=0的偏置进行复制信息
if ((unsigned int)identifier != PKG_HEADER_IDENTIFIER) {
return false;
//检查是否复制成功
}
int dataLen = GetIntFromBuf(data, AUTH_PACKET_HEAD_SIZE - sizeof(int));
if (dataLen + AUTH_PACKET_HEAD_SIZE >= RECIVED_BUFF_SIZE) {
return false;
}
int total = size;
int remain = dataLen;
while (remain > 0) {
size = TcpRecvData(session->fd, data + total, remain, 0);
remain -= size;
total += size;
}
//如果有接收到数据,就将用户发送的信息不断接收到data当中(位置为data首地址+total)
cJSON *receiveObj = TransFirstPkg2Json(data, dataLen + AUTH_PACKET_HEAD_SIZE);
if (receiveObj == NULL) {
return false;
}
int ret = AssignValue2Session(session, receiveObj);
cJSON_Delete(receiveObj);
if (ret != true) {
return false;
}
//以上为两种数据的类型转换
SessionListenerMap *sessionListener = GetSessionListenerByName(session->sessionName, strlen(session->sessionName));
//通过name来启动监听
if (sessionListener == NULL) {
return false;
}
if (!ResponseToClient(session)) {
SOFTBUS_PRINT("[TRANS] HandleRequestMsg ResponseToClient fail\n");
return false;
//响应到客户端
}
if (sessionListener->listener == NULL) {
return false;
}
if (sessionListener->listener->onSessionOpened == NULL) {
return false;
}
if (sessionListener->listener->onSessionOpened(session->fd) != 0) {
return false;
}
//检测会话监听和相关session是否打开
return true;
}
static void FreeSessionRecvMem(char* recvDataBuf, TcpSession* session)//释放会话接收成员
{
if (recvDataBuf != NULL) {
free(recvDataBuf);
//检查如果传入的数组recvDataBuf不为空,就释放空间。
}
if (session == NULL) {
return;
}
CloseSession(session->fd);//根据传入的session,获取套接字关闭相应文件设备
}
static int32_t TcpSessionRecv(TcpSession *session, const char* buf, uint32_t size, int timeout)
{
if (buf == NULL || session == NULL || session->fd head));//将&(node->head)插入链表session->seqNumList
int plainLen = DecryptTransData(&cipherKey, (unsigned char*)(recvDataBuf + TRANS_PACKET_HEAD_SIZE),
recvSize - TRANS_PACKET_HEAD_SIZE, (unsigned char*)buf, size);
//对cipherKey密钥进行加密
free(recvDataBuf);//释放数据缓冲
if (plainLen sessionName, "softbus_Lite_unknown") == 0) {
//比较会话名和softbus_Lite_unknown是否相同
bool isSuccess = HandleRequestMsg(session);
if (!isSuccess) {
//如果处理请求信息不成功就关闭session—>fd套接字对应设备
CloseSession(session->fd);
}
return isSuccess;
} else {//如果
unsigned char* buf = calloc(1, RECIVED_BUFF_SIZE);
if (buf == NULL) {
return false;
}
SOFTBUS_PRINT("[TRANS] OnProcessDataAvailable sessionName: %s, fd: %d\n", session->sessionName, session->fd);
SessionListenerMap *sessionListener = GetSessionListenerByName(session->sessionName,
strlen(session->sessionName));
if (sessionListener != NULL && sessionListener->listener != NULL) {
int recvLen = TcpSessionRecv(session, (char *)buf, RECIVED_BUFF_SIZE, 0);
if (recvLen listener->onBytesReceived(session->fd, buf, recvLen);
free(buf);
return true;
}
free(buf);
}
return false;
}
static void ProcessSesssionData(const TcpSessionMgr *tsm, const fd_set *rfds)
{
for (int i = 0; i sessionMap_[i] != NULL && tsm->sessionMap_[i]->fd != -1 &&
FD_ISSET(tsm->sessionMap_[i]->fd, rfds) > 0) {
if (!OnProcessDataAvailable(tsm->sessionMap_[i])) {
return;
}
}
}
}
static void ProcessData(TcpSessionMgr *tsm, fd_set *rfds)//来检查tsm变量的监听套接字是否在集合rfds中,在的话根据套接字连接监听的进程
{
if (tsm == NULL || tsm->listenFd == -1) {
return;
}
if (FD_ISSET(tsm->listenFd, rfds)) {
ProcessConnection(tsm);
return;
}
ProcessSesssionData(tsm, rfds);
}
static void FreeSessionMgr(void)//释放会话管理
{
free(g_sessionMgr);
g_sessionMgr = NULL;
}