365bet体育|www.635288com-365体育手机在线

热门关键词: 365bet体育,www.635288com,365体育手机在线

指向一个套接字结合

2019-11-28 作者:365bet体育   |   浏览(106)

windows socket编程select模型使用,socketselect

int select(

        int nfds,            //忽略         fd_ser* readfds,    //指向一个套接字集合,用来检测其可读性         fd_set* writefds,   // 指向一个套接字结合,用来检测其可写性         fd_ser* exceptfds, //指向一个套接字集合,用来检测错误         const struct timeval * timeout   //指定此函数等待的最长时间,如果为NULL,则最长时间为无限大。 );   参数说明: (1)   nfds  windows下未使用,linux下会使用此参数 (2)   readfds:   readfds集合中的套接字发送在以下三种情况中任意一种就会被视为可读,select函数返回后继续留在readfds集合中,不可读的会被移除readfds集合。 1.套接字有数据可读,可以对套接字调用recv函数接收数据 2.套接字的连接已经关闭,重启或者中断,此时应该对套接字进行关闭 3.listen被调用,并且有一个连接未决,对 listen套接字调用accept函数建立新的链接。 (3)   writefds:    readfds集合中的套接字在以下三种情况下会被视为可写 1.使用connect套接字首次建立链接 2.使用accept套接字被接收 3.使用send操作失败,返回WSAEWOULDBLOCK错误,而且缓冲区的空间变得可用 send出去的数据其实都先存在winsock的发送缓冲区中,然后才发送出去,如果缓冲区满了,那么再调用send(WSASend,sendto,WSASendTo)的话,就会返回一个 WSAEWOULDBLOCK的错误码,接下来随着发送缓冲区中的数据被发送出去,缓冲区中出现可用空间时,一个 FD_WRITE 事件才会被触发,这里比较容易混淆的是 FD_WRITE 触发的前提是 缓冲区要先被充满然后随着数据的发送又出现可用空间,而不是缓冲区中有可用空间 (4)   exceptfds   (未使用过,没有进行深入的研究) 1.如果一个非阻塞连接调用正在被处理,连接视图失败 2.OOB数据可读 (5)   timeout:   设置时间,如果超过设定时间,还没有网络事件发生,则返回0,如果此参数为NULL,select会无限等待,直到有一个描述字满足条件。 timeout指向一个timeval结构 typedef struct timeval {     long tv_sec;       //只是等待多少秒     long tv_usec;     //指示等待多少毫秒 } timeval; 如果timeval为{0,0},则select()立即返回,这可用于探询所 选套接口的状态。如果处于这种状态,则select()调用可认为是非阻塞的,且一切适用于非阻塞调用的假设都适用于它   具体编程流程 1.初始化套接字集合fdSocket,向这个集合添加监听套接字 2.将fdSocket集合拷贝到fdRead传递给select函数,当有时间发送时,select函数移除fdRead集合中没有未决io操作的套接字 3.比较原来fdSocket集合与select处理后的fdRead集合。确定哪些套接字有未决IO 4.回到第2步继续处理

 my_socket();
 my_bind(port);
 my_listen();

 //PostMessage(h_hand,WM_USER_THREADEND,0,0);


 //select模型处理过程
 //(1).初始化套接字集合fdSocket.添加监听套接字句柄到这个集合
 FD_ZERO(&fdSocket);
 FD_SET(sSock,&fdSocket);

 while (1)
 {

  //(2.)将fdSocket集合的一个拷贝fdRead传递给select函数
  //当有时间发生时,select函数一处fdRead集合中没有未决IO操作的套接字句柄,然后返回。
  fd_set fdRead = fdSocket;
  int nRet = select(0,&fdRead,NULL,NULL,NULL);    //timeout参数控制select()完成的时间。若timeout参数为空指针,则select()将一直阻塞
              //到有一个描述字满足条件。否则的话,timeout指向一个timeval结构,其中指定了select()
              //调用在返回前等待多长时间
              //fdwrite  1. 接成功的套接字  在第一次建立连接时,C/S端都会触发一个FD_WRITE事件
                //2, 触发的前提是 缓冲区要先被充满然后随着数据的发送又出现可用空间

  if(nRet>0)
  {
   //(3)通过原来的fdSocket集合与select处理后的fdRead集合比较
   //确定哪些套接字有未决io,并进一步处理这些io
   for(int i=0;i<(int)fdSocket.fd_count;i  )
   {
    if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
    {
     if(fdSocket.fd_array[i] == sSock)   //(1)监听套接字收到新连接,有新的链接
     {
      if(fdSocket.fd_count<FD_SETSIZE)   //判断集合满了吗?
      {

       int socke_len = sizeof(remoteAddr);


       //4.accept
       SOCKET cSock = accept(sSock,(SOCKADDR*)&remoteAddr,&socke_len);

       if(cSock == INVALID_SOCKET)
       {
        AfxMessageBox("accept failed!n");
        printf("accept failed!n");
        continue;
       }
       FD_SET(cSock,&fdSocket);

       //printf("接收到一个连接请求!:%srn",inet_ntoa(remoteAddr.sin_addr) );
       //printf("当前连接到服务器的客户端有 %d 个n",fdSocket.fd_count 1);
       socket_id = cSock*(-1);

       PostMessage(h_hand,WM_USER_THREADEND,0,0);

      }
      else
      {
       AfxMessageBox("too much connections !n");
       printf("too much connections n");
       continue;
      }

     }
     else
     {

      int nRecv = recv(fdSocket.fd_array[i],readText,sizeof(readText),0);
      socket_id = fdSocket.fd_array[i];
      if(nRecv>0)    //(2)可读
      {
       readText[nRecv] = '\0';

       //HWND   g_WindowHandle=((CDialog *)AfxGetMainWnd())->GetSafeHwnd();

       PostMessage(h_hand,WM_USER_THREADEND,0,0);
      }
      else           //(3)连接关闭,重启或中断
      {
       closesocket(fdSocket.fd_array[i]);
       FD_CLR(fdSocket.fd_array[i],&fdSocket);
       someone_out = TRUE;
       PostMessage(h_hand,WM_USER_THREADEND,0,0);
      }
     }
    }

   }


  }
  else
  {
   AfxMessageBox("failed select()]n");
   printf("failed select()]n");
   break;

  }

 }

 

以上只是我在项目中使用的部分代码,最开始的my_socket,my_bind,my_listen都是自己对socket,bind,listen自己重新做的封装

 

 

socket编程select模型使用,socketselect int select( int nfds, //忽略 fd_ser* readfds, //指向一个套接字集合,用来检测其可读性 fd_set* writefds, // 指...

本文由365bet体育发布于365bet体育,转载请注明出处:指向一个套接字结合

关键词: 365bet娱乐