select

发布时间 2023-04-12 21:37:40作者: 夜雾
#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();
  //}

}