一起学习CC3200系列教程之TCP ECHO 服务端 selcet

来源:互联网 发布:ps 淘宝 广告 编辑:程序博客网 时间:2024/06/04 18:27
一起学习CC3200系列教程之TCP  ECHO  服务端  selcet


         阿汤哥

序:

能力有限,难免有错,有问题请联系我,

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)



0 0