鸿蒙源码分析(十九)

您所在的位置:网站首页 鸿蒙系统源码解读教程 鸿蒙源码分析(十九)

鸿蒙源码分析(十九)

2023-09-03 07:13| 来源: 网络整理| 查看: 265

文章目录 coap_socket.c代码分析一、背景知识二、coap_socket.c代码详细分析2.1 套接字的获取2.2 socket两端(客户端、服务器)的创建2.3 数据的接收和发送 三、总结

coap_socket.c代码分析

本篇主题:本篇博客主要分析coap_socket.c相关代码 文件路径(软总线模块\discovery\coap\source\coap_socket.c)

一、背景知识

socket通信机制详解

二、coap_socket.c代码详细分析

该文件中主要分为三部分,分别为套接字的获取,socket两端(客户端、服务器)的创建,数据的发送和接收。

2.1 套接字的获取

这一部分主要使用函数来返回用户定义的全局变量g_serverFd、g_clientFd。实现套接字的获取

int g_serverFd = -1;//全局服务器套接字 int g_clientFd = -1;//客户端套接字 //用来获取coap服务器的套接字g_serverFd int GetCoapServerSocket(void) { return g_serverFd; } //用来获取coap客户端的套接字g_clientFd int GetCoapClientSocket(void) { return g_clientFd; } 2.2 socket两端(客户端、服务器)的创建

下面两部分代码主要实现客户端的创建和服务器的创建。 基于udp协议服务器的创建 该函数主要用来创建一个基于udp协议的服务器,而非trans_service下面的TCP协议。 实现套接字的创建和端口绑定(bind())的过程。

//创建一个服务器,传输协议为udp而非tcp int CoapCreateUdpServer(const struct sockaddr_in *sockAddr) { if (sockAddr == NULL) { return NSTACKX_EINVAL; //检查传入的啊承诺书是否为空 } struct sockaddr_in localAddr;//本地地址结构体 socklen_t len = sizeof(localAddr);// int sockfd = socket(AF_INET, SOCK_DGRAM, 0); //创建一个套接字 if (sockfd //如果端口的s_addr不为0 localAddr.sin_addr.s_addr = sockAddr->sin_addr.s_addr; //将sockaddr的s_addr写进localAttr } else { //s_addr为0,则localAttr对应的s_addr为htonl获取的地址 localAddr.sin_addr.s_addr = htonl(INADDR_ANY); } //将sockfd和localAddr相关联的端口设备进行绑定 if (bind(sockfd, (struct sockaddr *)&localAddr, len) == -1) { CloseSocket(&sockfd); //绑定失败就关闭套接字 return NSTACKX_EFAILED; } if (getsockname(sockfd, (struct sockaddr *)&localAddr, &len) == -1) { //获取套接字的名字,获取失败就关闭套接字 CloseSocket(&sockfd); return NSTACKX_EFAILED; } return sockfd;//最后返回所连接套接字 }

基于udp协议的客户端创建 该函数主要用来创建一个基于udp协议的客户端,中间使用到临时地址,最后将创建成功的服务器套接字写进定义的全局变量g_clientFd。

//和上方创建服务器类似,这里创建一个客户端 int CoapCreateUdpClient(const struct sockaddr_in *sockAddr) { if (sockAddr == NULL) { return NSTACKX_EFAILED; //用来检查传入的sockAddr } struct sockaddr_in tmpAddr;//定义一个临时的套接字地址 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); //创建生成一个新的套接字sockfd if (sockfd CloseSocket(&sockfd); return NSTACKX_EFAILED; //连接失败关闭套接字,函数返回 } socklen_t srcAddrLen = sizeof(struct sockaddr_in); (void)memset_s(&tmpAddr, sizeof(tmpAddr), 0, sizeof(tmpAddr)); //初始化临时的套接字地址,并获取临时套接字名字 ret = getsockname(sockfd, (struct sockaddr *)&tmpAddr, &srcAddrLen); if (ret != 0) { CloseSocket(&sockfd); return NSTACKX_EFAILED; //获取失败的处理 } CloseSocket(&g_clientFd); //关闭临时客户端 g_clientFd = sockfd; //并且将客户端套接字重置为新生成的套接字 return NSTACKX_EOK; } 2.3 数据的接收和发送

发送数据基于CoapSocketSend()函数 该函数的主要原理是将数据传送至指定目的缓冲区,可以实现未连接状态下的数据发送。这里主要是发送到socket->dstAddr对应的目的地缓冲区 sendto()函数参数详解:

s 套接字buff 待发送数据的缓冲区size 缓冲区长度Flags 调用方式标志位, 一般为0, 改变Flags,将会改变Sendto发送的形式addr (可选)指针,指向目的套接字的地址len addr所指地址的长度 //用来将数据发送到udp连接的另一端 int CoapSocketSend(const SocketInfo *socket, const uint8_t *buffer, size_t length) { if (buffer == NULL || socket == NULL) { return NSTACKX_EFAILED; } socklen_t dstAddrLen = sizeof(struct sockaddr_in); int ret = sendto(socket->cliendFd, buffer, length, 0, (struct sockaddr *)&socket->dstAddr, dstAddrLen); //sendto用来发送udp数据包,这里发送到ocket->dstAddr目的地缓冲区 return ret; }

接收数据基于CoapSocketRecv()函数 该函数主要实现数据的接收,基于recvfrom()函数接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间,参数len为可接收数据的最大长度.参数flags一般设0,其他数值定义参考recv().参数from用来指定欲传送的网络地址,结构sockaddr请参考bind()函数.参数fromlen为sockaddr的结构长度。 recvfrom()函数参数详解:

socketfd 套接字buffer 存放接收的数据len 可接收数据的最大长度 //用来接收数据经过socket int CoapSocketRecv(int socketFd, uint8_t *buffer, size_t length) { if (buffer == NULL || socketFd


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3