select模型应用

几个结构及函数原型:

int select(
  int nfds,                           
  fd_set FAR *readfds,               
  fd_set FAR *writefds,              
  fd_set FAR *exceptfds,             
  const struct timeval FAR *timeout  
);
typedef struct fd_set {
  u_int    fd_count;                 // how many are SET? 
  SOCKET   fd_array[FD_SETSIZE];     // an array of SOCKETs 
} fd_set;
 
struct timeval {
  long    tv_sec;         // seconds 
  long    tv_usec;        // and microseconds 
};

#include "stdafx.h"
#include <stdio.h>
#include <InitSock.h>

CInitSock theSock;//链接到winsock库的载入及释放(资源分配即初始化)
int main(int argc, char* argv[])
{
 USHORT nPort=4567;
 //创建监听套接字
 SOCKET sListen=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

 sockaddr_in sin;
 sin.sin_family=AF_INET;
 sin.sin_port=htons(nPort);
 sin.sin_addr.S_un.S_addr=INADDR_ANY;

 //绑定套接字到本地机器
 if (::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
 {
  printf("failed bind()/n");
  return -1;
 }
 
 //进入监听模式
 ::listen(sListen,5);

 //select模型处理过程
 //1. 初始化一个套接字集合fdSocket,添加监听套接字句柄到这个集合

 fd_set fdSocket;
 FD_ZERO(&fdSocket);
 FD_SET(sListen,&fdSocket);

 while (true)
 {
  //2) 将fdSocket的一个拷贝fdRead传递给select函数
  //当有事件发生时,select函数移出fdRead集合中没有未决io操作的套接字句柄,返回
  fd_set fdRead=fdSocket;
  int nRet=::select(NULL,&fdRead,NULL,NULL,NULL);
 // printf("hello/n");
  if (nRet>0)
  {
   //3)比较fdSocket和fdRead,确定未决io;
   for (int i=0;i<(int)fdSocket.fd_count;i++)
   {
   // printf("%d",(int)fdSocket.fd_count);
    if (FD_ISSET(fdSocket.fd_array[i],&fdRead))
    {
     if (fdSocket.fd_array[i]==sListen)//监听套接字接收新连接
     {
      if (fdSocket.fd_count<FD_SETSIZE)
      {
       sockaddr_in addrRemote;
       int nAddrLen=sizeof(addrRemote);
       SOCKET sNew=::accept(sListen,(sockaddr*)&addrRemote,&nAddrLen);
       FD_SET(sNew,&fdSocket);
       printf("接收到连接(%s)/n",::inet_ntoa(addrRemote.sin_addr));
      }
      else
      {
       printf("too much connections!/n");
       continue;
      }
     }
     else
     {
      char szText[256];
      int nRecv=::recv(fdSocket.fd_array[i],szText,strlen(szText),0);
      if (nRecv>0)//可读
      {
       szText[nRecv]='/0';
       printf("接收到数据:%s",szText);

      }
      else         //关闭连接,重启,中断
      {
       ::closesocket(fdSocket.fd_array[i]);
       FD_CLR(fdSocket.fd_array[i],&fdSocket);
      }
     }
    }
   }
  }
  else
  {
   printf("failed select()!/n");
   break;
  }
 }
 return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值