zoukankan      html  css  js  c++  java
  • Select模型的 单服务器多客户端示范代码

    #include <stdio.h>
    #include <iostream>
    #include <winsock2.h>
    using namespace std;
    int main(){
        WORD version = MAKEWORD(2,2);
        WSADATA wsaData;
        SOCKET listenSocket;
        SOCKET acceptSocket;
        SOCKET clientSocket[FD_SETSIZE];
        int static index = 0;
        DWORD block = 1L;
        FD_SET ReadSet;
       //加载SOCKET库

        int f = WSAStartup(version,&wsaData);
        if (f != 0){
            cout<<"加载Winsock 库错误! 错误号:"<<WSAGetLastError()<<endl;
            return -1;

        }

        //创建监听SOCKET

        listenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
        if (listenSocket == INVALID_SOCKET){
            WSACleanup();
            cout<<"创建监听SOCKET失败! 错误号:"<<WSAGetLastError()<<endl;
            return -1;

        }
        cout<<"监听SOCKET创建成功!\n"<<endl;

        //构造服务器地址

        SOCKADDR_IN serverIp;

                    serverIp.sin_family = AF_INET;
                    serverIp.sin_port = htons(8108);
                    serverIp.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
        if (bind(listenSocket,(SOCKADDR*)&serverIp,sizeof(SOCKADDR)) == SOCKET_ERROR){
            cout<<"绑定服务器错误! 错误号:"<<WSAGetLastError()<<endl;
            return -1;

        }

        cout<<"绑定操作成功!\n"<<endl;
        if (listen(listenSocket,10) == SOCKET_ERROR){
            cout<<"进入监听模式错误! 错误号:"<<WSAGetLastError()<<endl;
            return -1;
        }
        cout<<"服务器已进入监听模式!\n"<<endl;

        if (ioctlsocket(listenSocket,FIONBIO,&block) == SOCKET_ERROR){
    Cout<<"监听SOCKET设置为非阻塞模式错误! 错误号:"<<WSAGetLastError()<<endl;

            return -1;

        }

        cout<<"监听SOCKET已设置为非阻塞模式!\n\n\n"<<endl;


        //非阻塞模式接受客户端连接

        while(TRUE){

              cout<<"持续按非阻塞模式接受客户端连接请求!\n\n"<<endl;
              //将读SET 清0

              FD_ZERO(&ReadSet);

              //将已有客户端连接放到集合中!

              for (int i = 0; i < index; i  ){

            cout<<"将clientSocket["<<i<<"]放到ReadSet集合中!\n"<<endl;

                   FD_SET(clientSocket[i],&ReadSet);
              }
            cout<<"监听SOCKET 放入 ReadSet集合中!\n\n"<<endl;

              FD_SET(listenSocket,&ReadSet);
              if (select(0,&ReadSet,NULL,NULL,NULL) == SOCKET_ERROR

                  cout<<"select 监听SOCET错误! 错误号:"<<WSAGetLastError()<<endl;
                  system("pause");
                  return -1;
              }

              cout<<"select 返回 说明已有客户端进行连接或有客户端数据读取或有客户端连接断开!\n\n\n"<<endl;

                  if (FD_ISSET(listenSocket,&ReadSet)){

                      cout<<"当前ReadSet中存监听SOCKET!\n\n"<<endl;
                      acceptSocket = accept(listenSocket,NULL,NULL);
                      if (acceptSocket != INVALID_SOCKET){
                 cout<<"客户端建立连接成功并保存到clientSocket["<<index<<"]中!\n\n"<<endl;
                          clientSocket[index] = acceptSocket;
                          index++   ;

                      }else {
                          cout<<"接收客户端连接错误! 错误号:"<<WSAGetLastError()<<endl;

                       continue;

                      }
                  }

                  for (int j = 0; j < index; j  ){

                      if (FD_ISSET(clientSocket[j],&ReadSet)){
                          cout<<"当前ReadSet集合中有客户端SOCKET clientSocket["<<j<<"]可读数据!\n [message]"

                          char buffer[100]; memset(buffer,0,100);

                          if (recv(clientSocket[j],buffer,100,0) != SOCKET_ERROR){

                              cout<<buffer<<"[/messsage]\n"<<endl;

                          }else {

                              cout<<"客户端clientSocket["<<j<<"]出现错误! 错误号:"<<WSAGetLastError()<<endl;
                              clientSocket[j] = NULL;

                              index --;
                              closesocket(clientSocket[j])
                              break;

                          }


     }            }
        }
      }

    下面这段代码与上面所述的While(True)部分基本一致,但我本人感觉下面的方法更好.

    while(true)
     {

      fd_set fdRead=fdSocket;
      if (::select(0,&fdSocket,NULL,NULL,NULL)==SOCKET_ERROR)
      {
       continue;
      }
      else
      { 
      TRACE("Wait somebody % i\n ",fdSocket.fd_count);
      for(int i=0;i<(int)fdSocket.fd_count;i++)
      { 

       if(FD_ISSET( fdSocket.fd_array[i], &fdSocket))
       {
        if(fdSocket.fd_array[i]==sListen)   
        { 
         CString strIP;
         sockaddr_in addrRemote;
         int nAddrLen=sizeof(addrRemote);
         SOCKET sNew=::accept(sListen,(sockaddr*)&addrRemote,&nAddrLen);
         FD_SET(sNew,&fdSocket);
         strIP.Format( "%s",inet_ntoa(addrRemote.sin_addr) );
         TRACE("NEW COME    %s\n",strIP);

        }//end if ==slisten
        else
        {
         int nRecev=::recv(fdSocket.fd_array[i],(char*)&recvPacket,sizeof(recvPacket),0);
         if (nRecev>0)
         {
          TRACE("recv msg %s\n",recvPacket);

         }else
         {
          ::closesocket(fdSocket.fd_array[i]);
          FD_CLR(fdSocket.fd_array[i],&fdSocket);
         }
        }
       }
      
      }
      }
     }
      return 0;

  • 相关阅读:
    第四课:数字系统抽象
    第三课:叠加法和戴维南法
    第二课:基本电路法
    电路和电子学第一课:集总电路抽象
    第三十六课:告别演出
    第三十五课:多普勒效应和宇宙大爆炸
    第三十四课:光栅和分辨率
    第三十三课:干涉
    第三十二课:复习课
    第三十一集:彩虹
  • 原文地址:https://www.cnblogs.com/rainbowzc/p/1520113.html
Copyright © 2011-2022 走看看