Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Handling Multiple TCP Connections  (Read 18066 times)

0 Members and 1 Guest are viewing this topic.

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
Handling Multiple TCP Connections
« Reply #15 on: December 23, 2010, 12:58:28 am »
I'm not sure what you want to know... It's exactly the same as sending something to all clients except the sender. Skip over then in a client array.

EiTkoCaT

  • Newbie
  • *
  • Posts: 47
    • View Profile
Handling Multiple TCP Connections
« Reply #16 on: December 25, 2010, 02:17:24 pm »
Ok, so now it's not a problem to send all the connected users something I want.

But here's my problem now.. The server needs to handle that:
User A sends login request -> sent OK. Now the user is waiting.
User B sends login request -> sent OK. Now the user is waiting.
User C sends login request -> sent OK. Now the user is waiting.
Now user A just sent a load menu request. The server needs to find the menu of user A from the DB, and to send it to user A.
Now user B just sent a load menu request. The server needs to find the menu of user B from the DB, and to send it to user B.
Now user A just choosed the Enter World option from the menu. Then he sends to the server 'enter world'. The server is now searching in the DB where is in the world user A located. Then he sends to user A he's location.
Now user C just sent a load menu request. The server needs to find the menu of user C from the DB, and to send it to user C.
Now user C just choosed the Enter World option from the menu. Then he sends to the server 'enter world'. The server is now searching in the DB where is in the world user C located. Then he sends to user C he's location.
Now user A just jumped in the map. The server searching if there is another user in the same map. There is! User C. He sends to user C 'user A just jumped'


How can I handle that kind of things? It makes me crazy..! How can I recognize in the selector the reads the message what user sent the message and by the user search in the database?

Here's what I tried to do without a selector, but you can find my problem at http://www.sfml-dev.org/forum/viewtopic.php?p=25051#25051. It should just log in a user and wait for a load menu request. I can't handle here number of users trying to connect.


Code: [Select]
#include <iostream>
#include <sstream>
#include <string>
#include <SFML/Network.hpp>
#include <SFML/System.hpp>
#include "client/dbclient.h"
#include "Mongo.cpp"
#pragma comment( lib, "mongoclient" )

std::vector<sf::SocketTCP> Users;
std::vector<sf::IPAddress> UsersIP;
   sf::SocketTCP Server;
   sf::SocketTCP Client;
   sf::IPAddress ClientAddress;

int connectedClients = 0;
mongo::DBClientConnection c;
bool server_running;

bool LoginSeccedd;
void serverTCP(void* UserData);
sf::Thread ThreadTCP(&serverTCP);

using namespace std;


void startUserrt(sf::SocketTCP Client, sf::IPAddress ClientAddress) {

   /*Users.push_back(Client);
   UsersIP.push_back(ClientAddress);

   connectedClients++;
   
   for (int i=connectedClients; i<connectedClients;i++)
   {
      cout << ClientAddress[connectedClients] << endl;
   }*/

   char Message[256];
   std::size_t Received;
   if (Client.Receive(Message, sizeof(Message), Received) != sf::Socket::Done)
      return;
   // Show the message
   
   string stringAll, str3, str4;
   stringAll = Message;
   size_t found;
   size_t total = 0;
   string current_string[3];

   for (int i=0;i<3;i++)
   {
      cout << &Message[total] << endl;
      found = strlen(&Message[total]);
      current_string[i] = &Message[total];
      total += found + 1;
   }

   if (current_string[0] == "7L")
   {
      // Login
      cout << "Login requst" << endl;
      mongo::BSONObjBuilder query;
      query.append( "email" , current_string[1] ).append( "password", current_string[2] );
      mongo::BSONObj res = c.findOne( "test.users" , query.obj() );
      string userID = res["email"];
      cout << userID << endl;
   //   session_userEmail = userID;
   //   session_userID = res["_id"];
      if (userID == "EOO")
      {
         char ToSend2[] = "8L 0 not-found\0";
         if (Client.Send(ToSend2, sizeof(ToSend2)) != sf::Socket::Done)
            return;
         cout << ToSend2 << endl;
      }
      else
      {
         char ToSend2[] = "8L 1 1\0";
         if (Client.Send(ToSend2, sizeof(ToSend2)) != sf::Socket::Done)
            return;
         cout << ToSend2 << endl;
         LoginSeccedd = true;
      }
   }
   else if (current_string[0] == "7R")
   {
      // Register
      cout << "Register requst" << endl;
       mongo::BSONObjBuilder query;
      query.append( "email" , current_string[1] ).append( "password", current_string[2] );
      mongo::BSONObj res = c.findOne( "test.users" , query.obj() );
      string userID = res["email"];
      cout << userID << endl;
      if (userID == "EOO")
      {
         char ToSend2[] = "8R 1\0";
         // INSERT USER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!***********************************************************************
         if (Client.Send(ToSend2, sizeof(ToSend2)) != sf::Socket::Done)
            return;
         cout << ToSend2 << endl;
         LoginSeccedd = true;
      }
      else
      {
         char ToSend2[] = "8R 0 3\0";
         if (Client.Send(ToSend2, sizeof(ToSend2)) != sf::Socket::Done)
            return;
         cout << ToSend2 << endl;
      }
   }
   else
   {
      cout << "Unknow Request" << endl;
   }


   if (LoginSeccedd = true)
   {
      char Message[256];
      std::size_t Received;
      if (Client.Receive(Message, sizeof(Message), Received) != sf::Socket::Done)
         return;
      cout << Message << endl;
      if (Message == "7MM")
      {
         // Load Main Menu - send character information
         /*string ToSend2 = "8MM";
         mongo::BSONObjBuilder query;
         query.append( "user_id" , session_userID );

         auto_ptr<DBClientCursor> cursor =
         c.query("test.characters", query.obj() );
         while( cursor->more() ) {
            BSONObj p = cursor->next();
            cout << p["name"] << endl;
            ToSend2 += p["name"];
         }
         cout << ToSend2 << endl;*/
           
      }
      else if (Message == "7CC")
      {

      }
         
   }
}


void serverTCP(void* UserData) {
   while (server_running)
   {
      // Wait for a connection
       if (Server.Accept(Client, &ClientAddress) != sf::Socket::Done)
         return;
      cout << "Client connected : " << ClientAddress << std::endl;
      startUserrt(Client, ClientAddress);

            /*User *current;
         current = new User;
      current->startUserrt(Client);*/
   }
}




void startServer() {
   server_running = true;
       if (!Server.Listen(2435))
      return;
   
   cout << "Server is listening to port " << 2435 << ", waiting for connections... " << std::endl;
   ThreadTCP.Launch();
}

int main()
{
     c.connect("localhost"); //"192.168.58.1");
    cout << "connected ok" << endl;
startServer();

    // Wait until the user presses 'enter' key
    std::cout << "Press enter to exit..." << std::endl;
    std::cin.ignore(10000, '\n');
    std::cin.ignore(10000, '\n');

    return EXIT_SUCCESS;

}

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
Handling Multiple TCP Connections
« Reply #17 on: December 26, 2010, 09:44:40 am »
Use a 2-dimensional array, e.g. Clients[][]. In Clients[n][0], store the sockets of the clients. In Clients[n][1], store the corresponding username that was sent from that socket at login, when login succeeded. Then, you can search for the socket, get the corresponding username, and use that as you want.

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
Handling Multiple TCP Connections
« Reply #18 on: January 02, 2011, 10:33:47 am »
Have you managed to get it to work yet?

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Handling Multiple TCP Connections
« Reply #19 on: January 07, 2011, 09:09:33 pm »
Just something (maybe)not directly related to the topic:

If you create one thread per client, and there is a lot of clients, per say, 100... Don't you think 100 threads concurrently could be a bottleneck?

I'm not 100% sure of this, but i REALLY think that would simply waste the performance : ) Threads can be your friend, but also your enemy ;D

Spodi

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • http://www.netgore.com/
Handling Multiple TCP Connections
« Reply #20 on: January 07, 2011, 09:49:41 pm »
If you want to have a large number of high-performance connections, then yes, thread-per-socket is a horrible way to go. You'll want to use a different library for your networking, and use IOCP (when available) or asynchronous sockets to let the OS manage the threading for you and allow you to use event-based sockets.

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Handling Multiple TCP Connections
« Reply #21 on: January 07, 2011, 10:01:44 pm »
Exactly, i use ENET ;D
SFML Network is also awesome, but not for fast paced gaming in my opinion : ) I use it the most for HTTP stuff, like transfering files and apples : )