一起学习CC3200系列教程之TCP ECHO 服务端 selcet
2015-06-14 23:42
691 查看
一起学习CC3200系列教程之TCP ECHO 服务端 selcet
阿汤哥
序:
能力有限,难免有错,有问题请联系我,
QQ1519256298 hytga@163.com
Pdf下载http://pan.baidu.com/s/1hqiWB56
关键字:tcp 服务端 select 非阻塞
软件流程:创建一个tcp服务端,可以连接多个客户端,当客户端有数据发过来,就把数据原封不动地发回去。使用的是select机制。
select:软件阻塞于select函数,select可以用来判断有没有新的连接及新的数据通过这个select,可以实现非阻塞的读。
直接上源码:这是一个任务,所有的操作都在这里
宏定义
序:
能力有限,难免有错,有问题请联系我,
QQ1519256298 hytga@163.com
Pdf下载http://pan.baidu.com/s/1hqiWB56
关键字:tcp 服务端 select 非阻塞
软件流程:创建一个tcp服务端,可以连接多个客户端,当客户端有数据发过来,就把数据原封不动地发回去。使用的是select机制。
select:软件阻塞于select函数,select可以用来判断有没有新的连接及新的数据通过这个select,可以实现非阻塞的读。
直接上源码:这是一个任务,所有的操作都在这里
void vTcpEchoServerUseSelect(void *pvParameters) { SlSockAddrIn_t xServer,xClient; int szWatchList[mainWATCH_LIST_MAX]; int iSockFD,iMaxFD,iListenFD,iConnectFD; int i,temp,iAddrSize,iRetVal,iRc; SlSocklen_t xAddrLen; char szBuf[200]; SlFdSet_t xFds; struct SlTimeval_t tv; tv.tv_sec = 20; tv.tv_usec = 0; //设置网络, //为什么需要这里设置? //因为本网络设置需要启动任务调度器:这个任务需要调度器去调度VStartSimpleLinkSpawnTask这个任务 //如果没有启动调度器,会导致wlan连不上。 WlanInit(); iAddrSize = sizeof(SlSockAddrIn_t); UART_PRINT("\r\nvTcpEchoServerUseSelect\r\n"); //创建监听端口 iListenFD = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); if( iListenFD < 0 ){ //出错处理:略 UART_PRINT("\r\n sl_Socket \r\n"); } //设置ip及端口信息 xServer.sin_family = SL_AF_INET; xServer.sin_port = sl_Htons((unsigned short)9000); xServer.sin_addr.s_addr = SL_INADDR_ANY; iRetVal = sl_Bind(iListenFD,(SlSockAddr_t *) &xServer,sizeof(xServer)); if (iRetVal < 0 ) { //出错处理:略 UART_PRINT("\r\n sl_Bind \r\n"); } //创建监听,listen队列中等待的连接数为2 iRetVal = sl_Listen(iListenFD,10); if (iRetVal < 0 ) { //出错处理:略 UART_PRINT("\r\n sl_Listen \r\n"); } for (i = 0;i < mainWATCH_LIST_MAX;i++){ //初始化监听的socket szWatchList[i] = -1; } //设置监听的socket集的第一个为服务端的socket szWatchList[0] = iListenFD; iMaxFD = iListenFD; while(1) { //清除监听集合 SL_FD_ZERO(&xFds); //清空 //初始化监听集合, for (i = 0 ;i < mainWATCH_LIST_MAX;i++) { if (szWatchList[i] != -1) { SL_FD_SET(szWatchList[i],&xFds); } } UART_PRINT("\r\n start sl_Select \r\n"); //参数:socket句柄的最大值加1,可读的监听集合,可写的监听集合,出错的监听集合,溢出的时间 //select就是根据监听的集合去判断有哪些socket可读,可写。。 //首先我们把xFds看出一个集合而不是一个int,便于理解 //譬如,xfds 里面有1 ,2 ,3 ,4, //当1可读,4可读 //函数返回后sfds里面有1,4 iRc = sl_Select(iMaxFD + 1,&xFds,0,0,&tv); switch(iRc) { case -1: UART_PRINT("\r\n sl_Select \r\n"); break; case 0: UART_PRINT("\r\n 超过延时了 \r\n"); break; default: //判断服务端的sokcet有没有在监听的集合里 if (SL_FD_ISSET(iListenFD,&xFds)) { //新的连接 UART_PRINT("iListenFD\r\n"); xAddrLen = sizeof(xClient); //进行接受 iRetVal = sl_Accept(iListenFD,(struct SlSockAddr_t *)&xClient,&xAddrLen); if (iRetVal < 0) { UART_PRINT("\r\n sl_Accept \r\n"); } else { for (i = 0 ;i < mainWATCH_LIST_MAX;i++) { if (szWatchList[i] == -1) { //存储socket句柄 szWatchList[i] = iRetVal; UART_PRINT("\r\n 新的连接:%d:%d \r\n",i,szWatchList[i]); break; } } if ( i == mainWATCH_LIST_MAX) { UART_PRINT("\r\n 请注意:太多连接了 \r\n"); } else { if (iMaxFD < iRetVal) { iMaxFD = iRetVal; } } } } { for (i = 1 ;i < mainWATCH_LIST_MAX;i++) { if (szWatchList[i] == -1) { continue; } if (!SL_FD_ISSET(szWatchList[i],&xFds)){ continue; } //有数据可读 iRetVal = sl_Recv(szWatchList[i],szBuf,200,0); if (iRetVal <= 0 ) { sl_Close(szWatchList[i]); szWatchList[i] = -1; //因为我们是在阻塞的模式下,连接关闭的时候,会读到0, //所以我们就先直接关闭了。 UART_PRINT("\r\n sl_Recv %d \r\n",iRetVal); } else { iRetVal = sl_Send(szWatchList[i],szBuf,iRetVal,0); if (iRetVal < 0) { UART_PRINT("\r\n sl_Send \r\n"); } } } } } } }
宏定义
#define mainWATCH_LIST_MAX (0x10)
相关文章推荐
- 菜鸟网络业务支撑平台
- listview+BaseAdapter + AsyncTask异步请求网络 + LruCache缓存图片
- android http通信
- Allegro里隐藏GND或者电源网络的鼠线/ 显示隐藏的鼠线,修改网络颜色
- 【转】HTTP协议详解
- 大学课程--计算机网络
- Ubuntu 编译安装 Linux 4.0.5 内核,并修复 vmware 网络内核模块编译错误
- Android网络编程
- 黑马程序员<Java笔记<GUI 网络编程反射>>
- Linux 网络之IP转换
- TCP/IP协议族-----5、IPv4地址
- linux下的网络连接方式 NAT
- Python实战之神经网络(1)
- C#网络编程 tcpclient (阻塞异步)
- 【iOS开发-网络】AFN的使用
- APP测试框架(整合网络资源版)_Phoenix-晶
- Android开发之Http通信HttpClient接口
- HTTP协议学习
- 黑马程序员——网络编程2:网络通讯组件介绍及演示-上
- 黑马程序员——网络编程1:网络通讯原理简介