返回请求连接的tcp客户端的socket句柄;当没有新的客户端连接请求到达或协议栈报错时返回INVALID_SOCKET,具体的错误码通过penErr参数获得 。
示例
EN_ONPSERR enErr;……SOCKET hSockSrv = socket(AF_INET, SOCK_STREAM, 0, &enErr);if(INVALID_SOCKET != hSockSrv){if(!bind(hSockSrv, NULL, 6411)) //* 绑定成功{if(!listen(hSockSrv, usBacklog)) //* 进入监听状态{//* 循环等待并处理到达的tcp连接请求while(1){in_addr_t unCltIP;USHORT usCltPort;SOCKET hSockClt = accept(hSockSrv, &unCltIP, &usCltPort, 1, &enErr);if(INVALID_SOCKET != hSockClt) //* 返回了一个有效的客户端socket句柄{//* 新的客户端到达,在这里增加你的自定义代码……}else{//* 错误码为ERRNO代表无错误发生 , 意味着没有新的客户端连接请求到达,回到循环开始处继续等待即可if(ERRNO == enErr)continue;else //* 不等于ERRNO意味着协议栈报错,需要处理{……printf("%s\r\n", onps_error(enErr)); //* 打印错误信息}}}}else //* 失败printf("%s\r\n", onps_get_last_error(hSocket, NULL)); //* 打印错误信息}else //* 绑定失败printf("%s\r\n", onps_get_last_error(hSocket, NULL)); //* 打印错误信息}elseprintf("%s\r\n", onps_error(enErr)); //*打印错误信息……
返回目录tcpsrv_recv_poll功能
阻塞/非阻塞型,tcp服务器数据接收专用函数,等待任意一个或多个tcp客户端数据到达信号 。协议栈利用rtos提供的信号量实现了一个poll模型,当有一个及以上的tcp客户端数据到达 , 均会触发一个信号到用户层,我们通过tcpsrv_recv_poll()函数等待这个信号 。这个函数的第二个参数值表示这个函数最长等待多少秒 , 等待期间有任意一个或多个客户端数据到达则立即返回最先到达的这个客户端的socket,继续调用这个函数则继续返回下一个客户端socket,直至返回一个无效的socket才意味着当前所有已送达的数据均已读取完毕,已经没有任何客户端有新数据到达了 。
原型
SOCKET tcpsrv_recv_poll(SOCKET hSocketSrv, INT nWaitSecs, EN_ONPSERR *penErr);
入口参数
- hSocketSrv:tcp服务器的socket句柄
- nWaitSecs:等待时长,单位:秒 。0,不等待,立即返回;大于0 , 等待指定时间直至收到一个/多个客户端数据到达信号或超时;小于0,一直等待,直至收到一个/多个客户端数据到达信号或协议栈报错
- penErr:指向错误编码的指针 , 函数执行失败时该参数用于接收实际的错误码
返回已经收到数据的tcp客户端的socket句柄;当没有任何tcp客户端收到数据或协议栈报错时返回INVALID_SOCKET,具体的错误码通过penErr参数获得 。
示例
//* 完成tcp服务器的数据读取工作void tcp_server_recv(void *pvData){SOCKET hSockClt;EN_ONPSERR enErr;INT nRcvBytes;UCHAR ubaRcvBuf[100];while(TRUE){hSockClt = tcpsrv_recv_poll(l_hSockSrv, 1, &enErr);if(INVALID_SOCKET != hSockClt) //* 有效的socket{//* 注意这里一定要尽量读取完毕该客户端的所有已到达的数据,因为每个客户端只有新数据到达时才会触发一个信号到用户层//* ,如果你没有读取完毕就只能等到该客户端送达下一组数据时再读取了,这可能会导致数据处理延迟问题while(TRUE){//* 读取数据nRcvBytes = recv(hSockClt, ubaRcvBuf, 256);if(nRcvBytes > 0){//* 原封不动的回送给客户端 , 利用回显来模拟服务器回馈应答报文的场景send(hSockClt, ubaRcvBuf, nRcvBytes, 1);}else //* 已经读取完毕{if(nRcvBytes < 0){//* 协议栈底层报错 , 这里需要增加你的容错代码处理这个错误并打印错误信息printf("%s\r\n", onps_get_last_error(hSocket, NULL));}break;}}}else //* 无效的socket{//* 返回一个无效的socket时需要判断是否存在错误,如果不存在则意味着1秒内没有任何数据到达,否则打印这个错误if(ERRNO != enErr)printf("tcpsrv_recv_poll() failed, %s\r\n", onps_error(enErr));}}}
返回目录socket_get_last_error/onps_get_last_error功能
获取socket最近一次发生的错误,包括描述信息及错误编码 。该函数其实是前面示例代码中出现的onps_get_last_error()函数的二次封装,功能及使用方式与之完全相同 。
原型
const CHAR *socket_get_last_error(SOCKET socket, EN_ONPSERR *penErr);
入口参数
- socket:socket句柄
- penErr:指向错误编码的指针 , 该参数用于接收实际的错误码
返回值为字符串指针,指向socket最近一次发生的错误描述字符串 。
示例
略 。
返回目录
推荐阅读
- 索尼wf1000xm4怎么连接_索尼wf1000xm4使用说明
- 3 onps栈移植说明——添加网卡
- 2 onps栈移植说明——编译器及os适配层移植
- 1 onps栈移植说明——onps栈的配置及裁剪
- 开源网络协议栈onps诞生记
- <一>从指令角度了解函数堆栈调用过程
- 漫步者funbuds怎么配对_漫步者funbuds使用说明
- 3 Python全栈工程师之从网页搭建入门到Flask全栈项目实战 - 入门Flask微框架
- 都卷Java,你看看你得学多少技术栈才能工作!
- flutter系列之:flutter中可以建索引的栈布局IndexedStack