更多内容请访问:51CTOOpenHarmony技术社区https://ost.51cto.com一、前言承接上篇项目介绍,本文将详细介绍如何在熊派上搭建一个TCP服务器来处理各种客户端的请求。本文适用于小型系统和标准系统。您可以将此工程移植到满足上述条件的开发板上。配置相应的编译规则。二、准备工作1.BearPi-HMMicro一台。2、一台已经配置好熊派开发环境的电脑。3.将BearPi连接到局域网。3、流程介绍编写TCP服务器的C文件-->配置BUILD.gn-->添加编译我们的代码-->编译烧录。4.网络开发基础知识OpenHarmony上的网络开发与Linux上的网络开发非常相似,都是使用C语言的套接字(Socket)开发。在进行网络开发之前,如果没有相关基础,建议了解OSI网络模型和TCP/IP协议的关系。这次使用Socket进行传输层的开发,使用了一点应用层的HTTP协议。(1)什么是Socket在计算机通信领域,socket译为“套接字”,是计算机之间的一种约定或通信方式。通过套接字协议,一台计算机可以从其他计算机接收数据,也可以向其他计算机发送数据。一句话总结:socket是一个集成TCP/IP协议的工具。让我们不用过多关注底层协议的实现,直接使用封装好的socket即可。(2)TCP通信过程在开始使用socket之前,我们需要知道TCP服务器和TCP客户端之间的通信过程。我们熊派要实现的就是图中9的右半部分,也就是TCP服务器端。我们一步步来看,每一步都有对应的代码实现。第一步:socket()函数用于创建socket套接字,可以理解为在对象中创建对象,但并不等价。第二步:bind()函数用于绑定IP和端口,即选择你的TCP服务器在哪个IP和端口上提供服务。第三步:listen()函数用于监听上一步选择的IP和端口。第四步:accept()函数用于等待客户端的连接,即进入阻塞状态。第五步:当有客户端请求时,read()函数会读取客户端发送的请求数据。第六步:write()函数可以向客户端返回数据。这个操作是可选的,也可以不向客户端返回任何数据。第七步:read()和write()操作可以重复执行,也就是不断的相互通信。当通信完成后,执行close函数关闭socket。(3)相关函数解释创建socketsocketintsocket(intdomain,inttype,intprotocol);参数介绍domain:协议域,也称为协议族(family),常用的协议族有AFLINET、AFINET6、AFLOCAL(或AFUNIX,Unix成socket)AFROUTE等。协议族决定了套接字的地址类型,通信时必须使用对应的地址。例如,AFINET决定使用ipv4地址。(32位“组合”和端口号(16位),AFUNIX决定使用绝对路径名作为地址。type:指定Socket类型。常用的socket类型有SOCKSTREAM,SOCKDGRAM,SOCKRAW,SOCKPACKET、SOCKSEQPACKET等流式套接字(SOCKSTREAM)是一种面向连接的Socket,针对面向连接的TCP服务应用。数据报套接字(SOCKDGRAM)是一种无连接的Socket,对应于连接的UDP服务应用。protocol:指定协议,常用的协议有IPPROTOTCP、IPPROTOUDP、IPPROTOSTCP、IPPROTOTIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议,当参数为o时,会自动选择第二个参数type对应的默认协议注意:type和protocol不能随意组合,比如SOCKSTREAM不能和1PPROTOUDP组合返回值:如果调用成功,则会返回新创建的socket的描述符,失败则返回INVALIDSOCKET(Linux下失败则返回-1)。绑定端口函数intbind(intsocketfd,conststructsockaddr*addr,socklen_taddrlen)参数介绍socketfd:标识连接套接字的描述词。address:是一个sockaddr结构体指针,包含要合并的地址和端口号。address_len:确定地址缓冲区的长度。注意:sockaddr的地址结构根据地址创建套接字时的地址协议族不同而不同。返回值:如果函数执行成功,返回值为0,否则为SOCKET_ERROR。启动监听函数intlisten(intsocketfd,intbacklog)参数介绍socketfd:要监听的socket描述字。backlog:相应socket可以排队的最大连接数。等待连接阻塞函数intaccept(intsocketfd,structsockaddr*addr,socklen_t*addrlen);参数介绍socketfd:就是上面解释的监听socket,这个socket是用来监听一个端口的,当有client和server连接的时候,就使用当前socket关联的端口号。当然,客户端并不知道socket的详细信息,只知道一个地址和一个端口号。sockaddr:result参数,用于接受一个返回值,指定客户端的地址。当然,这个地址是用地址结构来描述的,用户应该知道这是一种什么样的地址结构。如果您对客户的地址不感兴趣,可以将此值设置为NULL。len:也是result的参数,用来接受上面addr结构体的大小,已经指明了addr结构体占用的字节数。同样,也可以设置为NULL。注意:默认情况下,accept会阻塞进程,直到客户端连接建立并返回。它返回一个新的可用套接字,即连接套接字。返回值:成功返回客户端的文件描述符,失败返回-1。-如果accept返回成功,说明服务器和用户已经正确建立了连接,此时服务器通过accept返回的socket完成了与客户端的通信。5、连接函数intconnnect(intsockfd,conststructsockaddr*addr,socklen_taddrlen)参数介绍socketfd:客户端套接字的描述字。socketaddr:服务器的套接字地址。addrlen:套接字地址长度发送函数发送函数有两个:ssize_twrite(intsockfd,constvoid*buf,szie_tnbytes);参数介绍sockfd是要写入文件的描述符。buf为待写入数据的缓冲区地址。nbytes是要写入的数据字节簿。返回值:成功返回写入的字节数,失败返回-1。intsend(intsockfd,constvoid*buf,intlen,intflags)参数介绍sockfd是要写入文件的描述符。buf为待写入数据的缓冲区地址。len是要写入的数据字节簿。flags有如下选项,MSG_DONTROUTE是不查找路由表;MSG_OOB是接受或发送带外数据;MSGPEEK是查看数据,不会从系统缓冲区中移除数据;MSGWAITALL是等待任何数据;0和写函数的操作是一样的。返回值:成功返回写入的字节数,失败返回-1。接受函数还有两个接受函数:ssize_tread(intsockfd,constvoid*buf,szie_tnbytes);参数介绍sockfd是要读取的文件的描述符。buf是要读取的数据的缓冲区地址。nbytes是要读取的数据字节簿。返回值:成功返回读取的字节数,失败返回-1。intrecv(intsockfd,constvoid*buf,intlen,intflags)参数介绍sockfd是要写入文件的描述符。buf为待写入数据的缓冲区地址。len是要写入的数据字节簿。flags有如下选项,MSG_DONTROUTE是不查找路由表;MSG_OOB是接受或发送带外数据;MSGPEEK是查看数据,不会从系统缓冲区中移除数据;MSGWAITALL是等待任何数据;0和写函数的操作是一样的。返回值:成功返回写入的字节数,失败返回-1。更多信息请访问:51CTOOpenHarmony技术社区https://ost.51cto.com
