首页 > 其他分享 >select

select

时间:2023-04-12 21:46:49浏览次数:29  
标签:mpSocks fs sock siClient nRet include select

#include <iostream>
#include <thread>
#include <vector>
#include <map>
using namespace std;

#define FD_SETSIZE 1024
#include <winsock2.h>
#include <windows.h>

void Handle(SOCKET sock, sockaddr_in siClient)
{
    //接受数据
    char szBuff[MAXBYTE] = {};
    int nRet = recv(sock, szBuff, sizeof(szBuff), 0);
    if(nRet == 0 || (nRet == SOCKET_ERROR) && WSAGetLastError() == WSAECONNRESET)
    {
      //连接关闭
      printf("ip:%s port:%d connection closed \r\n",
        inet_ntoa(siClient.sin_addr),
        ntohs(siClient.sin_port));
      return;
    }
    else if (nRet == SOCKET_ERROR)
    {
    }

    printf("ip:%s port:%d msg:%s \r\n",
      inet_ntoa(siClient.sin_addr),
      ntohs(siClient.sin_port),
      szBuff);

    char szSend[] = { "recv ok" };
    nRet = send(sock, szSend, sizeof(szSend), 0);
    if (nRet == SOCKET_ERROR)
    {
      cout << "send failed" << endl;
    }
}


int main()
{
  //创建socket
  SOCKET sockServer = socket(AF_INET, 
    SOCK_STREAM, //数据流
    IPPROTO_TCP  //tcp协议
    );
  if (sockServer == INVALID_SOCKET)
  {
    cout << "socket failed" << endl;
    return 0;
  }

  //绑定端口
  sockaddr_in si;
  si.sin_family = AF_INET;
  si.sin_port = htons(0x9527);
  si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

  int nRet = bind(sockServer, (sockaddr*)&si, sizeof(si));
  if (nRet != 0)
  {
    cout << "bind failed" << endl;
    return 0;
  }

  //监听
  nRet = listen(sockServer, SOMAXCONN);
  if (nRet == SOCKET_ERROR)
  {
    cout << "listen failed" << endl;
    return 0;
  }

  map<SOCKET, sockaddr_in> mpSocks; //连接的socket数组
  mpSocks[sockServer] = si;
  while (true)
  {
    fd_set fs;
    FD_ZERO(&fs);
    for (auto sock:mpSocks)
    {
      /*fs.fd_array[fs.fd_count] = sock;
      ++fs.fd_count;*/
      FD_SET(sock.first, &fs);
    }

    timeval tv = {1, 0};
    int nRet = select(mpSocks.size(), &fs, NULL, NULL,  &tv);
    if (nRet == 0)
    {
      cout << "超时" << endl;
      continue;
    }
    else if(nRet == SOCKET_ERROR)
    {
      cout << "出错" << endl;
      continue;
    }

    //有数据可读了
    for (size_t i = 0; i < fs.fd_count; i++)
    {
      if (fs.fd_array[i] == sockServer)
      {
        //接受连接    
          sockaddr_in siClient = {};
          int nNameLen = sizeof(siClient);
          SOCKET sock = accept(sockServer, (sockaddr*)&siClient, &nNameLen);
          if (sock == INVALID_SOCKET)
          {
            cout << "accept failed" << endl;
            continue;
          }
          mpSocks[sock] = siClient;
      }
      else
      {
        //接受数据
        Handle(fs.fd_array[i], mpSocks[fs.fd_array[i]]);
      }
    }
  }


  //while (true)
  //{
  //  //接受连接
  //  sockaddr_in siClient = {};
  //  int nNameLen = sizeof(siClient);
  //  SOCKET sock = accept(sockServer, (sockaddr*)&siClient, &nNameLen);
  //  if (sock == INVALID_SOCKET)
  //  {
  //    cout << "accept failed" << endl;
  //    return 0;
  //  }
  //  printf("ip:%s port:%d connected \r\n",
  //    inet_ntoa(siClient.sin_addr),
  //    ntohs(siClient.sin_port));


  //  //启动线程,收发数据
  //  thread(Handle, sock, siClient).detach();
  //}

}

 

标签:mpSocks,fs,sock,siClient,nRet,include,select
From: https://www.cnblogs.com/yewu1/p/17311376.html

相关文章

  • mouted阶段无法通过querySelectAll获取dom元素
    要获取的元素是通过v-for渲染出来的时候,dom元素依赖的数据是通过异步请求获取的,mouted时v-for的数据还没有获取到,故没有元素产生,mouted无法获取元素,可以使用nexttick和watch结合来用,监听dom元素依赖的数据变化,用nextTick来管理数据,在数据获取之后再获取dom元素......
  • Golang基础-- select的用法
    select是golang在语言层面提供的多路IO复用的机制,其可以检测多个channel是否ready三个题目示例来说明一下select的大概作用:题目一:声明两个channel,分别为chan1和chan2,依次启动两个协程,分别向两个channel中写入一个数据就进入睡眠。select语句两个case分别检测chan1和chan2是......
  • select下拉框处理
    1.selectByIndex()根据索引来选取,从0开始2.selectByValue()根据属性value的属性值来选取3.selectByVisibleText()根据标签之间的Text值,也就是页面显示的注意:导入的包要正确不然会报错。  importorg.openqa.selenium.support.ui.Select;单选下拉列表:HTML源码<tr>......
  • MySQL Others--select @@tx_read_only 执行频率较高问题
    问题描述MySQLJDBCDriver在5.1.36以下的版本且数据库版本大于5.6.5,在每次update/insert/delete请求时,均会向后端数据库发送select@@tx_read_only命令,判断下当前会话的事务是否是只读。MySQLJDBCDriver在5.1.36以上,如果使用execute()而不是executeUpdate()方......
  • jeesite #form中获取控件的值,以绑定的treeselect为例
    绑定部分代码:<divclass="form-group"><#form:formid="searchForm"model="${iotDevice}"action="${ctx}/iot/iotItem/listGroupData"method="post"class="form-inline"......
  • Golang基础-Select
    基本概念select是Go中的一个控制结构,类似于switch语句。select语句只能用于通道(channel)操作,每个case必须是一个通道操作,要么是发送要么是接收。select语句会监听所有指定的通道上的操作,一旦其中一个通道准备好就会执行相应的代码块。如果多个通道都准备好,那么sel......
  • 45、K8S-调度机制-节点调度之nodeAffinity、nodeName、nodeSelector
    Kubernetes学习目录1、配置解析1.1、简介我们知道,默认的调度策略有可能无法满足我们的需求,我们可以根据实际情况,定制自己的调度策略,然后整合到k8s的集群中。1.2、属性解析apiVersion:kubescheduler.config.k8s.io/v1beta1kind:KubeSchedulerConfigurationAlgorithmSou......
  • ALL/ALLEXCEPT/ALLSELECTED
     ALL:ALL('TABLE'[COLUMN])或者ALL('TABLE')取消COLUMN的上下文过滤或者取消TABLE的上下文过滤 ALLEXCEPT:ALLEXCEPT('TABLE','TABLE'[COLUMN])取消COLUMN以外的上下文过滤 ALLSELECTED:ALLSELECTED('TABLE'[COLUMN])内筛选器ALL,外筛选器SELECTE......
  • Select all in address bar of firefox (Ubuntu, Linux Mint) with a single click
    Toomanythingstomodifyafterinstallingubuntuorlinuxmint.OneoftheannoyingthingisClickingtheaddressbaronFirefox(providedwithUbuntu,linuxmint)doesn’tselectthewholetextinit.Itsaverysmallproblem.Butitssoannoyingthat,t......
  • Oracle 执行Update 或 select for update 是卡着
    原因和解决方法这种只有update无法执行其他语句可以执行的其实是因为记录锁导致的,在oracle中,执行了update或者insert语句后,都会要求commit,如果不commit却强制关闭连接,oracle就会将这条提交的记录锁住。通过执行下列语句查询当前卡着的会话SELECTs.sid,s.serial#FROMv$l......