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

Author Topic: Troubles with bi-directional communication.  (Read 5299 times)

0 Members and 1 Guest are viewing this topic.

drpitch

  • Newbie
  • *
  • Posts: 18
    • View Profile
Troubles with bi-directional communication.
« on: May 14, 2009, 10:22:20 am »
Hi!

I'm in troubles to make sockets work when server is sending and receiving data. I need some help ;)

There are two server threads(TS1, TS2) and one client thread (TC).

TS1 does:
- Listen
- loop with:
    - Select
    - if it's a new client -> Send message to a dialog window
    - if it's a known client -> Receive (should receive the "POTATOE" string sent by the client [see below]).

TS2 does:
- Receives the message sent to the dialog window (WM_COMMAND) and calls to Send("INIT")

TC does:
- Receive (and it's blocked until TS2 sends the "INIT" string)
- Send("POTATOE")

Well, the thing is that TC receives the INIT string and sends the POTATOE string to the server, but the server doesn't receive "POTATE" but "INIT" string.

I'm launching server and client application on the same host, but this should not be a problem since server and clients are on different ports.

drpitch

  • Newbie
  • *
  • Posts: 18
    • View Profile
Troubles with bi-directional communication.
« Reply #1 on: May 14, 2009, 06:12:49 pm »
Hi again ;)

Here I provide a complete and minimal sample code which demonstrates what is happening.

If you take a look at the sample code, the server should receive a SET_ISNEAR command, but is receiving a SET_BEGIN!

Code: [Select]

#include <iostream>
#include <sstream>
#include <SFML/Network.hpp>


struct UserEventPkt
{
sf::Uint32   Op;
sf::Uint32   Par1;
sf::Uint32   Par2;    
};

enum UserEvent
{
SET_POSITION,
SET_PRESSURE,
SET_ISNEAR,
SET_ISTRIGGERDOWN,
SET_BEGIN
};


sf::Packet& operator <<(sf::Packet& Packet, const UserEventPkt& C)
{
    return Packet << C.Op << C.Par1 << C.Par2;
}

sf::Packet& operator >>(sf::Packet& Packet, UserEventPkt& C)
{
    return Packet >> C.Op >> C.Par1 >> C.Par2;
}


int main()
{
sf::SelectorTCP Selector;
sf::SocketTCP Listener;
sf::Packet packet;
UserEventPkt e;
sf::SocketTCP Client;


// Client or server ?
  char Who;
  std::cout << "Do you want to be a server ('s') or a client ('c') ? ";
  std::cin  >> Who;
if (Who == 's')
  {
if(!Listener.Listen(4567))
{
printf("Can't listen");
exit(0);
}

Selector.Add(Listener);

while(true)
{
unsigned int NbSockets = Selector.Wait();

for(unsigned int i = 0; i < NbSockets; ++i)
{
sf::SocketTCP Socket = Selector.GetSocketReady(i);

if (Socket == Listener)
{
// If the listening socket is ready, it means that we can accept a new connection
sf::IPAddress Address;
Listener.Accept(Client, &Address);
std::cout << "Client connected ! (" << Address << ")" << std::endl;

// Add it to the selector
Selector.Add(Client);

e.Op = SET_BEGIN;
e.Par1 = 0;
e.Par2 = 0;

// Send INIT to Client
packet << e;
Client.Send(packet);
}
else
{
// Else, it is a client socket so we can read the data he sent
sf::Packet Packet;
if (Socket.Receive(Packet) == sf::Socket::Done)
{
UserEventPkt e;

Packet >> e;

switch(e.Op)
{
case SET_POSITION:
printf("Set Position from Client");
break;

case SET_PRESSURE:
printf("Set Pressure from Client");
break;

case SET_ISNEAR:
printf("Set IsNear from Client");
break;

case SET_ISTRIGGERDOWN:
printf("Set IsTriggerDown from Client");
break;

case SET_BEGIN:
printf("Set Begin from Client");
break;

default:
std::cout << "A client says : " << e.Op << "(" << e.Par1 << "," << e.Par2 <<  ")" << std::endl;
}
}
else
{
// Error : we'd better remove the socket from the selector
Selector.Remove(Socket);
}
}        
}
}
}
else // Client
{
if (Client.Connect(4567, "127.0.0.1") != sf::Socket::Done)
{
std::cout << "Client can't connect to server" << std::endl;
exit(0);
}

while(true)
{
if (Client.Receive(packet) == sf::Socket::Done)
{
packet >> e;
if(e.Op == SET_BEGIN)
{
printf("SET BEGIN received!");
}
}
e.Op = SET_ISNEAR;
e.Par1 = 0;
e.Par2 = 0;
packet << e;
Client.Send(packet);
}
}
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Troubles with bi-directional communication.
« Reply #2 on: May 14, 2009, 07:03:49 pm »
You never clear your packet, so the data is accumulating in it and the server always extracts the first thing that you've put into it ;)
Laurent Gomila - SFML developer

drpitch

  • Newbie
  • *
  • Posts: 18
    • View Profile
Troubles with bi-directional communication.
« Reply #3 on: May 14, 2009, 10:54:02 pm »
Oops, thanks  :D

When should I clear the packet? Just after sending each packet and just after copying the packet to the "e" variable (using operator >>)?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Troubles with bi-directional communication.
« Reply #4 on: May 14, 2009, 11:06:52 pm »
Quote
When should I clear the packet?

Well... when you don't want the previous data to be in it anymore ;)
Laurent Gomila - SFML developer

drpitch

  • Newbie
  • *
  • Posts: 18
    • View Profile
Troubles with bi-directional communication.
« Reply #5 on: May 15, 2009, 12:45:11 pm »
:lol:

Thanks!