C++中I/O模型之select模型实例

本文实例讲述了C++中I/O模型的select模型用法。分享给大家供大家参考。具体实现方法如下:

代码如下:

void main() 

    CInitSock initSock; 
    USHORT nPort = 9999; //监听的端口 
    SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (sListen == INVALID_SOCKET) 
    { 
        printf("socket error..."); 
        return; 
    } 
    sockaddr_in servAddr = {0}; 
    servAddr.sin_family = AF_INET; 
    servAddr.sin_port = ::htons(nPort); 
    servAddr.sin_addr.S_un.S_addr = INADDR_ANY;  
    if (SOCKET_ERROR == ::bind(sListen, (sockaddr*)&servAddr, sizeof(servAddr))) 
    { 
        int nError = ::GetLastError(); 
        printf("connect error.."); 
        return; 
    } 
    ::listen(sListen, 5); 
 
     
    //select模型处理过程 
    //1.初始化套接字集合,添加监听socket到这个集合 
    fd_set  fdSocket; 
    FD_ZERO(&fdSocket); 
    FD_SET(sListen, &fdSocket); 
    while (TRUE) 
    { 
        //2. 将集合的一个拷贝传递给select函数 
        //当有事件发生时,select移除未决的socket,然后返回   就是说select返回时 集合的中socket就是发生事件的socket 
        fd_set fdRead = fdSocket; 
        int nRet = ::select(0, &fdRead, NULL, NULL, NULL); 
        if (nRet > 0) 
        { 
            //通过比较原来的fdSocket集合与经过处理的fdRead集合 
            for (UINT i=0;i<fdSocket.fd_count;i++) 
            { 
                if (FD_ISSET(fdSocket.fd_array[i], &fdRead)) //就是这个触发了 
                { 
                    if (fdSocket.fd_array[i] == sListen) //监听套接字接收到新连接  为神马分两种情况:因为触发Read集合的情况有两种:有连接来了或数据可读了.... 
                    { 
                        // 
                        if (fdSocket.fd_count < FD_SETSIZE) //FD_SETSIZE=64 
                        { 
                            sockaddr_in addrRemote = {0}; 
                            int nAddrLen = sizeof(addrRemote); 
                            SOCKET sNew = ::accept(sListen, (sockaddr*)&addrRemote, &nAddrLen); 
                            FD_SET(sNew, &fdSocket); 
                        } 
                        else     
                        { 
                            printf("too many connection...error"); 
                            continue; 
                        } 
                    } 
                    else  //有可读的 
                    { 
                        char szContent[256]={0}; 
                        int nRecv = ::recv(fdSocket.fd_array[i], szContent, sizeof(szContent), 0); 
                        if (nRecv > 0) 
                        { 
                            szContent[nRecv] = '\0'; 
                            printf("recv data:%s", szContent); 
                        } 
                        else //没读到数据 
                        { 
                            ::closesocket(fdSocket.fd_array[i]); 
                            FD_CLR(fdSocket.fd_array[i], &fdSocket); 
                        } 
                    } 
                } 
            } 
        } 
        else 
        { 
            printf("nRet litter 0, error..."); 
            return; 
        } 
    } 
    ::closesocket(sListen); //与socket配对写 
    printf("*******************************"); 
    getchar(); 
}

效果如下图所示:

希望本文所述对大家的C++程序设计有所帮助。

(0)

相关推荐

  • C++计算ICMP头的校验和实例

    本文实例讲述了C++计算ICMP头的校验和的方法,分享给大家供大家参考.具体实现代码如下: 复制代码 代码如下: USHORT checksum(USHORT* buff, int nSize)  {      unsigned long cksum=0;      //将数据以字为单位加到cksum      while (nSize > 1)      {          cksum += *buff++;          nSize -= sizeof(USHORT);      } 

  • C++之Boost::array用法简介

    本文实例讲述了c++里支持静态数组的容器:boost.array.分享给大家供大家参考.具体分析如下: 很多C++程序员都认为boost.array很有可能出现在下一代标准库里.对于boost.array的用法有一个基本的了解是很有必要的. 1. 为什么我们需要固定大小的数组的容器 首先,固定大小的数组还是很常见的,虽然stl提供了vector,但是vector作为动态可增长的数组,比静态数组多了一点开销,这在一些人看来是无法忍受的.c++里也需要提供固定大小容量的数组容器,当然,性能可以和普通

  • C++之BOOST字符串查找示例

    本文实例讲述了C++中BOOST字符串查找的方法,分享给大家供大家参考.具体方法如下: BOOST  字符串查找示例 复制代码 代码如下: #include <string>  #include <iostream>  #include <algorithm>  #include <functional>  #include <boost/algorithm/string/case_conv.hpp>  #include <boost/al

  • C++之boost::array的用法

    本文实例讲述了C++之boost::array的用法,分享给大家供大家参考.具体如下: 复制代码 代码如下: #include <string>  #include <iostream>  #include <boost/array.hpp>  #include <algorithm>  using namespace std;  int main()  {      boost::array<int, 5> array_temp = {{12,

  • C++实现ping程序实例

    本文实例讲述了C++实现ping程序的方法.分享给大家供大家参考.具体实现方法如下: 该实例涉及ICMP数据包的发送与回显,PING程序代码如下: 复制代码 代码如下: DWORD WINAPI ThreadProc(LPVOID lParam) {  CInitSock initSock;    HWND hWnd = (HWND)lParam; //从参数得到句柄  char szIp[64] ={0};  ::GetDlgItemTextA(hWnd, IDC_IP, szIp, size

  • c++ String去除头尾空格的方法

    本文实例讲述了c++ String去除头尾空格的方法,分享给大家供大家参考.具体实现方法如下: 实现该功能可使用string的find_first_not_of,和find_last_not_of方法,具体实现带如下: 复制代码 代码如下: #include <iostream> #include <string> std::string& trim(std::string &); int main() {     std::string s = " He

  • C++模板类的用法

    本文实例讲述了C++模板类的用法,分享给大家供大家参考.具体实现方法如下: main.h头文件如下: 复制代码 代码如下: template <class T>  class actioncontainer  {  public:      //构造函数      actioncontainer()      {          m_nRedoPos = 0;          m_nUndoPos = 0;      }      //容器的接口函数      void add(T val

  • C++广播通信实例

    本文实例讲述了C++实现广播通信的方法.分享给大家供大家参考.具体实现方法如下: 广播通信代码框架: 1. 协议都是: 复制代码 代码如下: SOCKET s = ::socket(AF_INET, SOCK_DGRAM, 0); 2. 服务端设置选项 复制代码 代码如下: BOOL bBroadcast = TRUE;  ::setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL)); 3. 服务端向255

  • C++设置超时时间的简单实现方法

    本文实例讲述了C++设置超时时间的简单实现方法,代码简单易懂,功能实用.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: BOOL SetTimeOut(SOCKET s, int nTime, BOOL bRecv)  {      int ret = ::setsockopt(s, SOL_SOCKET, bRecv?SO_RCVTIMEO:SO_SNDTIMEO, (char*)nTime, sizeof(nTime));      return ret!=SOCKET_ER

  • VC++获得当前进程运行目录的方法

    本文实例讲述了VC++获得当前进程运行目录的方法,分享给大家供大家参考.具体实现方法如下: 该实例主要通过利用windows API获得,具体代码如下: 复制代码 代码如下: CString GetAppPath() {   CString strAppPath;  // 保存结果   TCHAR szModuleFileName[MAX_PATH]; // 全路径名   TCHAR drive[_MAX_DRIVE];  // 盘符名称,比如说C盘啊,D盘啊   TCHAR dir[_MAX_

  • C++取得当前时间的方法

    本文实例讲述了C++取得当前时间的方法,分享给大家供大家参考. 具体实现方法如下: 复制代码 代码如下: //取本地时间  BOOL GetTime(string &mytime)  {      BOOL b_ret = TRUE;      CHAR szBuf1[256]={0};      CTime   tNow   =   CTime::GetCurrentTime();       sprintf(szBuf1,"%04u%02u%02u%02u%02u%02u"

随机推荐