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

Author Topic: TCP - send and recive data  (Read 2919 times)

0 Members and 1 Guest are viewing this topic.

mimipim

  • Newbie
  • *
  • Posts: 49
    • View Profile
TCP - send and recive data
« on: June 19, 2011, 11:38:15 am »
I have some problems, I'm not familiar with the TCP protocol.

If I send data to server for example:

Msg1: Hello!
- Server recieved: Hello!

Okay.

But if I send:

Msg2: Hello World!
 - Server recieved: Hello
World!

I'm using sf::Package.

That I'm interested is there any way to get data like it is sended(inline)?
 :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
TCP - send and recive data
« Reply #1 on: June 19, 2011, 12:52:07 pm »
This is not very clear. Could you show your code?
Laurent Gomila - SFML developer

mimipim

  • Newbie
  • *
  • Posts: 49
    • View Profile
TCP - send and recive data
« Reply #2 on: June 19, 2011, 05:03:22 pm »
Yep.

This class are writen from someone shared on sfml forum:

cpp:
Code: [Select]
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include <SFML/Network.hpp>

#include "network.h"

CNetwork::CNetwork()
{
    port = 5432;
    this->timeout = 5;
    state = ready;
}

CNetwork::CNetwork( int port, float timeout )
{
    this->port = port;
    this->timeout = timeout;
    state = ready;
}

CNetwork::~CNetwork()
{
    Client.Close();
}

bool CNetwork::Connect( sf::IPAddress ClientAddress )
{
    if ( state == connected ) return false;

    this->ClientAddress = ClientAddress;
    if (!this->ClientAddress.IsValid())
        return false;

    Client.SetBlocking(true);
    if ( Client.Connect(5432, this->ClientAddress, timeout) == sf::Socket::Done )
        state = connected;
    else
        state = timed_out;
    Client.SetBlocking(false);

    return (state == connected);
}

bool CNetwork::WaitConnection()
{
    switch(state)
    {
        case connected: return false;
        case ready:
            Server.SetBlocking(false);
            Server.Listen(port);
            state = waiting;
        case waiting:
            if (Server.Accept(Client, &ClientAddress) == sf::Socket::Done)
            {
                state = connected;
                Client.SetBlocking(false);
                Server.Close();
                return true;
            }
        default:
            return false;
    }
}

bool CNetwork::WaitData( sf::Packet* Packet )
{
    if ( state != connected ) return false;

    switch(Client.Receive(*Packet))
    {
        case sf::Socket::Done: return true;
        case sf::Socket::Disconnected:
            state = lost;
        default:
            return false;
    }

    return false;
}

bool CNetwork::SendData( sf::Packet* Packet )
{
    if ( state != connected ) return false;

    switch(Client.Send(*Packet))
    {
        case sf::Socket::Done:
            Packet->Clear();
            return true;
        case sf::Socket::Disconnected:
            state = lost;
        default:
            return false;
    }

    return false;
}


.h:
Code: [Select]
#ifndef NETWORK_H_INCLUDED
#define NETWORK_H_INCLUDED

#include <SFML/Network.hpp>

enum EState
{
    ready = 0,
    waiting,
    connected,
    timed_out,
    lost
};

class CNetwork
{
public:
    CNetwork();
    CNetwork( int port, float timeout );
    ~CNetwork();

    bool WaitConnection();
    bool Connect( sf::IPAddress ClientAddress );
    bool WaitData( sf::Packet* Packet );
    bool SendData( sf::Packet* Packet );

    float timeout;
    int port;
    EState state;
    sf::IPAddress ClientAddress;
    sf::SocketTCP Server;
    sf::SocketTCP Client;
};

template <class T>
class CMessage
{
    uint32_t id;
    uint32_t len;
    T data;
};

template <class T>
sf::Packet& operator <<(sf::Packet& Packet, const CMessage<T>& C)
{
    return Packet << C.id << C.len << C.data;
}

template <class T>
sf::Packet& operator >>(sf::Packet& Packet, CMessage<T>& C)
{
    return Packet >> C.id >> C.len >> C.data;
}

#endif


main function on server:
Code: [Select]

#include "network.h"
#include <iostream>
#include <string>

int main()
{
    CNetwork Network;

    sf::Packet ToSend;
    sf::Packet Recieved;

    bool runn = true;

    while(runn)
    {
        Network.WaitConnection();
        if ( Network.WaitData(&Recieved) )
        {
            std::string data;
            Recieved >> data;
            std::cout<<data<<std::endl;
            Recieved.Clear();
        }
    }

    return 0;
}


main function on client:
Code: [Select]

#include "network.h"
#include <iostream>
#include <string>

std::string doMsg(std::string &var)
{
    var = "";
    std::cout<<"\n[Message]: ";
    std::cin>>var;

    return var;
}

int main()
{
    CNetwork Network;

    sf::Packet ToSend;
    sf::Packet Recieved;

    std::string serverIp;
    unsigned short serverPort;

    std::cout<<"Connect to: ";
    std::cin>>serverIp;
    std::cout<<"Server port: ";
    std::cin>>serverPort;

    Network.port = serverPort;
    Network.Connect(sf::IPAddress(serverIp));
    bool runn = true;

    std::cout<<"\n\nPreparing.... Please be patient.\n\n";

    std::string msg;

    while(doMsg(msg) != "\0")
    {

        if(msg == "!quit")
        {
            runn = false;
        }

        if (msg.length() > 0)
        {
            ToSend.Clear();
            ToSend << msg;
            // fill ToSend packet...
            if (!Network.SendData(&ToSend))
            {
                std::cout<<"Oupss.. Something going wrong!";
            }
        } else std::cout<<"Invalid data (\0 ;))";
    }

    return 0;
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
TCP - send and recive data
« Reply #3 on: June 19, 2011, 05:55:41 pm »
You're probably sending two different packets: one with "Hello" and the other with "World!". This is because "cin >> str" use space as a separator. To get the full line (ie. use only \n as the separator) use the std::getline function.
Laurent Gomila - SFML developer

mimipim

  • Newbie
  • *
  • Posts: 49
    • View Profile
TCP - send and recive data
« Reply #4 on: June 20, 2011, 01:58:31 am »
Can someone explain me these things please:

1) Is possible to bind to one TCP socket 4 clients(at one time) and they won't be disconnected if game is not finished.

2) If not, how to make multiplayer game for 4 players using TCP socket?

3) What exactly means that TCP is blocking or not?

4) Is this method good: If client connect to server, he(client) start sending data about hes position on the map, server recive this data and send it back to client, than move client to recived positions(reciving and others players positions). (That's example of my algorith how server and clients to work(communicate), I'll be very happy if someone share better way or give me advice)?

I'm absolute newbie to socket programming.

:oops: