title: Winsock send call is very slow
body: <p>I am making a gameserver (TCP) which might need to handle 3000+ connections.
  Currently its having 50 connections and i am already experiencing lags.</p>
  
  <p>I found out that its the winsock send() calls that takes about 100~300ms each to return, which pretty much slow down the whole server as it is a single threaded server.</p>
  
  <p>So far I've thought about two solutions.</p>
  
  <ol>
  <li>Redesign my server to create a thread for each client (Is it really stable to create 3000+ threads for 3000 clients?).</li>
  <li>Find a way to make the send() call to return immediately.</li>
  </ol>
  
  <p>This is my socket init code:</p>
  
  <pre><code>int ret = WSAStartup(MAKEWORD(2,2), &amp;wsaData);
  if(ret != 0) 
  { 
      printf("Winsock failed to start.\n");
      system("pause");
      return; 
  }
  
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_port = htons(52000);
  
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if(sock == INVALID_SOCKET) 
  { 
      printf("Invalid Socket.\n");
      system("pause");
      return; 
  }
  
  if(bind(sock, (sockaddr*)&amp;server, sizeof(server)) != 0)
  { 
      printf("error");
      return; 
  }
  
  if(listen(sock, 5) != 0)
  {
      printf("error");
      return;
  }
  </code></pre>
  
  <p>Accepting code in a separate thread</p>
  
  <pre><code>sockaddr_in from;
  int fromlen = sizeof(from);
  SOCKET sTmpSocket = accept(ServerSock, (struct sockaddr*)&amp;from, &amp;fromlen);
  </code></pre>
  
  <p>My send function</p>
  
  <pre><code>void CClient::SendPacket(BYTE* pPacket, DWORD Len)
  {
      DWORD ToSendLen = Len;
      while (ToSendLen)
      {
          int iResult = send(this-&gt;ClientSocket, (char*)(pPacket + Len - ToSendLen), ToSendLen, 0);
  
          if (iResult == SOCKET_ERROR)
              return;
  
          ToSendLen -= iResult;
      }
  }
  </code></pre>
  
  <p>This is my server thread (incomplete, only relevant part)</p>
  
  <pre><code>while (1)
  {
      for (int i = 0; i &lt; MAX_CLIENT; i++)
      {
          if (Clients[i].bConnected == false)
              continue;
  
          timeval timeout;
          timeout.tv_sec = 0;
          timeout.tv_usec = 1;
          fd_set socketset;
          socketset.fd_count = 1;
          socketset.fd_array[0] = Clients[i].ClientSocket;
          if (select(0, &amp;socketset, 0, 0, &amp;timeout))
          {
              int RecvLen = recv(Clients[i].ClientSocket, (char*)pBuffer, 10000, MSG_PEEK);
              if (RecvLen == SOCKET_ERROR)
              {
                  Clients[i].bConnected = false;
                  iNumClients--;
              }
              else if (RecvLen == 0)
              {
                  Clients[i].bConnected = false;
                  iNumClients--;
              }
              else if (RecvLen &gt; 0)
              {
                  // Packet handling here
                  recv(Clients[i].ClientSocket, (char*)pBuffer, dwDataLen, MSG_WAITALL);
  
                  //...
              }
          }
      }
  
      Sleep(1);
  }
  </code></pre>
  
  <p>Any help would be greatly appreciated.
  Thank you.</p>