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

Author Topic: Client identification  (Read 26628 times)

0 Members and 1 Guest are viewing this topic.

Dummie

  • Newbie
  • *
  • Posts: 25
    • View Profile
Client identification
« on: June 26, 2008, 04:22:37 pm »
Hey,

I'm using a selector and all works fine but I don't know how to identificate clients. For example I want to give them numbers. Is there a nice way to do this with help of SFML?

Code: [Select]

const unsigned int numSockets = selector.Wait();

for (unsigned int i = 0; i < numSockets; ++i)
{
sf::SocketTCP socket = selector.GetSocketReady(i);

if (socket == listener)
{
sf::IPAddress address;
sf::SocketTCP client;
listener.Accept(client, &address);
selector.Add(client);
}
else
{
char recvBuf[1024];
size_t received;
if (socket.Receive(recvBuf, sizeof(recvBuf) - 1, received) != sf::Socket::Done)
// ---------->  - 1 is needed, I think. But I didn't see it in tutorial.
{
selector.Remove(socket);
std::cerr << "Error: receive" << std::endl;
continue;
}
recvBuf[received] = '\0'; // ---------->  This is needed, I think. But I didn't see it in tutorial.

std::cout << "Client (" << i << ") : " << recvBuf << std::endl; // ----------> I hoped I could give numbers to them this way. But all clients got the number 0.

std::string sndBuf;
sndBuf = "Thanks for the message: ";
sndBuf.append(recvBuf);

if (socket.Send(sndBuf.c_str(), sndBuf.length()) != sf::Socket::Done)
{
selector.Remove(socket);
std::cerr << "Error: Send" << std::endl;
continue;
}
}
}


Any suggestions?

Thanks in advance,
Dummie

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Client identification
« Reply #1 on: June 26, 2008, 05:11:15 pm »
Hi

A socket is internally just an integer identifier, and SFML socket classes expose this through comnparison operators so that you can use a socket instance as an identifier.

About your comments :
Quote
- 1 is needed, I think. But I didn't see it in tutorial

I don't get it, why -1 ? For what ?

Quote
This is needed, I think. But I didn't see it in tutorial

In the tutorial, I send the ending \0 and read it back on the other side, so I don't need to append it manually ;)

Quote
I hoped I could give numbers to them this way. But all clients got the number 0

Yep, i is the index among the sockets which are ready at the time you read them ; most of time there will only be one socket to read, so i is always 0.
Laurent Gomila - SFML developer

Dummie

  • Newbie
  • *
  • Posts: 25
    • View Profile
Client identification
« Reply #2 on: June 26, 2008, 06:40:30 pm »
Quote from: "Laurent"
Hi

A socket is internally just an integer identifier, and SFML socket classes expose this through comnparison operators so that you can use a socket instance as an identifier.

About your comments :
Quote
- 1 is needed, I think. But I didn't see it in tutorial

I don't get it, why -1 ? For what ?

Quote
This is needed, I think. But I didn't see it in tutorial

In the tutorial, I send the ending \0 and read it back on the other side, so I don't need to append it manually ;)

Quote
I hoped I could give numbers to them this way. But all clients got the number 0

Yep, i is the index among the sockets which are ready at the time you read them ; most of time there will only be one socket to read, so i is always 0.


Thank you for the answer. The -1 isn't needed. I made a mistake. Sorry :)

But something else in here:
http://www.sfml-dev.org/tutorials/1.3/network-sockets.php

Code: [Select]

char Buffer[] = "Hi guys !";
if (Client.Send(Buffer, sizeof(Buffer)) != sf::Socket::Done)
{
    // Error...
}


Are you sure sizeof(Buffer) is right? Wouldn't it be more right to use strlen(Buffer)?

workmad3

  • Jr. Member
  • **
  • Posts: 71
    • View Profile
Client identification
« Reply #3 on: June 26, 2008, 09:02:32 pm »
sizeof(Buffer) is perfectly valid and suitable there. sizeof when used on a static sized array will give you the size of the type (in this case, char so 1) multiplied by the size of the array.

Using strlen() would actually be less suitable for sending network packets. If you used a union like this:
Code: [Select]

template<typename T>
union conversion
{
   char cRep[sizeof(T)];
   T nRep;
};

in order to package arbitrary classes as network data then using strlen would be an error as it would bomb out if you had any 0 values in the class.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Client identification
« Reply #4 on: June 27, 2008, 02:52:13 am »
sizeof(Buffer) will send all the bytes in Buffer, including the ending \0. Which is not the case if I use strlen ;)
Laurent Gomila - SFML developer

Dummie

  • Newbie
  • *
  • Posts: 25
    • View Profile
Client identification
« Reply #5 on: June 27, 2008, 12:21:26 pm »
I understand now. Thanks a lot :)

But I got another problem. How would be a receive loop done?

Code: [Select]

char recvBuf[1024];
size_t received;
for (;;)
{
sf::Socket::Status status = client.Receive(recvBuf, sizeof(recvBuf), received);
if (status != sf::Socket::Done)
{
std::cerr << "Error: receive" << std::endl;
return 1;
}

if (received == 0)
break;

recvBuf[received] = '\0';
std::cout << "Server: " << recvBuf << std::endl;
}



Thanks in advance,
Dummie