Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML NETWORK] Problem z działaniem prostego komunikatora

Ostatnio zmodyfikowano 2013-11-17 11:44
Autor Wiadomość
domin568
Temat założony przez niniejszego użytkownika
[SFML NETWORK] Problem z działaniem prostego komunikatora
» 2013-11-02 15:17:07
Witam, zaczynam programować w SFML Network. Napisałem prostą aplikacje klient - server do czatowania. Jednak nie mogę doprowadzić aby można było z tego korzystać.
SERVER
C/C++
#include "stdafx.h"
#include <SFML/Network.hpp>

#include <iostream>

using namespace std;
const short PORT = 5000;
int main( int argc, char * argv[] )
{
    char data[ 100 ];
    char data_wyslana[ 100 ];
    size_t odebrany_rozmiar;
    bool running = true;
    sf::TcpSocket socket;
    socket.setBlocking( false );
    sf::TcpListener listener;
    listener.listen( PORT );
    sf::Packet pakiet_wysylany;
    sf::Packet pakiet_odbierany;
    if( listener.accept( socket ) == sf::Socket::Done )
    {
        cout << "Polaczono z : " << socket.getRemoteAddress() << endl;
    }
   
    while( running )
    {
       
        if( socket.receive( pakiet_odbierany ) == sf::Socket::Done )
        {
           
            pakiet_odbierany >> data;
            cout << data << endl;
            cout << "Odbieram pakiet :" << data << endl;
        }
        cin.getline( data, 100 );
        pakiet_wysylany << data;
        if( socket.send( pakiet_wysylany ) != sf::Socket::Done )
        {
            cout << "Nie udalo sie wyslac danych " << endl;
        }
        else
        {
            cout << "Wysylam Dane : " << data << endl;
        }
       
    }
    return 0;
}

KLIENT
C/C++
#include "stdafx.h"
#include <SFML/Network.hpp>
#include <iostream>
#include <cstdlib>
using namespace std;
int main( int argc, char * argv[] )
{
    cout << "Klient" << endl;
    char data[ 100 ];
    char data_odebrana[ 100 ];
    size_t odebrana_wielkosc;
    bool wyjscie = true;
   
    cout << "Wpisz adres ip : " << endl;
    string adres_ip_string;
    cin >> adres_ip_string;
   
    sf::Packet pakiet_wysylany;
    sf::Packet pakiet_odbierany;
   
    sf::TcpSocket socket;
   
   
    sf::Socket::Status status = socket.connect( adres_ip_string, 5000 );
   
    if( status != sf::Socket::Done )
    {
        cout << "Nie mozna polaczyc " << endl;
    }
    else if( status == sf::Socket::Done )
    {
        cout << "Polaczono" << endl;
        wyjscie = false;
       
        while( wyjscie == false )
        {
           
            cin.getline( data, sizeof( data ) );
           
            pakiet_wysylany << data;
            if( socket.receive( pakiet_odbierany ) == sf::Socket::Done )
            {
               
                pakiet_odbierany >> data_odebrana;
                cout << data_odebrana << endl;
                cout << "Odbieram dane :" << data_odebrana << endl;
            }
            if( pakiet_wysylany.getDataSize() > 0 )
            {
                if( socket.send( pakiet_wysylany ) != sf::Socket::Done )
                {
                    cout << "Nie udalo sie wyslac danych " << endl;
                }
            }
            else
            {
                cout << "Wysylam dane :" << data << endl;
            }
           
        }
       
    }
   
    system( "pause" );
    return 0;
}
Problem jest takiego rodzaju :
*Jeżeli połączę się klientem z serverem, to nie mogę nic napisać na kliencie
*Napiszę jakiś tekst na serverze, wszystko dobrze się wysyła i przechodzi do klienta
*Jeżeli po tym napiszę na kliencie jakiś tekst to nie mam odpowiedzi zwrotnej "Wysyłam dane" i tak jakby się wszystko zapycha. (Oczywiście na server nic nie jest przesyłane )

Myślę że jest to kwestia w dobraniu w odpowiednim miejscu funkcji
setBlocking()
 , jednak nie mogę tego zrozumieć jak to zrobić. Czy ktoś się na tym zna ? Z góry dzięki za ewentualną pomoc :)
P-95089
DejaVu
» 2013-11-03 23:06:56
Zrób komunikację nieblokującą - w przeciwnym wypadku będziesz musiał zrobić osobny wątek do odbierania pakietów.
P-95231
domin568
Temat założony przez niniejszego użytkownika
» 2013-11-04 14:59:40
Czyli w kliencie i serverze ustawić socket na setBlocking (false) ???
P-95254
RazzorFlame
» 2013-11-06 15:01:29
Cały styl tego komunikatora jest nieprawidłowy. Dla komunikatorów zaleca się użycia sposobu Client-Client a nie Client-Server. Poza tym jeślibyś już na prawdę musiał w ten sposób robić ten komunikator to radziłbym Ci zająć się dokumentacją SFML'a dla modułu Network. Sockety blokujące jak sama nazwa wskazuje blokują program do czasu wykonania żądanej akcji. Czyli jeśli czekasz na pakiet a twój socket jest blokowany to tak jak byś zrobił pętle przy użyciu socketów nieblokujących:
C/C++
//socket.setBlocking(false);
sf::Packet packet;
while( socket.receive( packet ) != sf::Socket::Done ) {
}
C/C++
//socket.setBlocking(true);
sf::Packet packet;
socket.receive( packet );
Te dwa zapisy są praktycznie takie same a raczej wykonają podobne akcje. Podobne dlatego że prawdopodobnie SFML jako że jest wydajną biblioteką, to jej autor nie mógłby sobie pozwolić na tak powolne zagranie :)
P-95459
domin568
Temat założony przez niniejszego użytkownika
» 2013-11-06 15:25:53
Postąpiłem według wskazówek DejaVu, stworzyłem wątek który odbiera dane . Ale z klienta nic nie mogę wysłać ( bo jak sprawdzałem to wysyła pakiet (pusty) zanim coś wogóle napisze do wysłania ), a jeżeli wyślę z servera do klienta to klient odbierze dobrze, ale jeżeli napisze coś innego 2 razem to tekst odbierany na kliencie nie zmienia się ( wysyłam np. Hello za 1 razem z servera do klienta, wiadomość dochodzi do klienta, pokazuje się , piszę Cześć , a na kliencie nadal pokazuje się Hello jako tekst odebrany )

kod :
Klient :
C/C++
#include "stdafx.h"
#include <SFML/Network.hpp>
#include <iostream>
#include <cstdlib>
using namespace std;

sf::TcpSocket socket;
sf::Mutex globalMutex;
void odbierz_pokaz_dane()
{
    static string oldMsg;
    while( true )
    {
       
        string msg;
        sf::Packet pakiet_odbierany;
       
        if( socket.receive( pakiet_odbierany ) == sf::Socket::Done )
        {
            if( pakiet_odbierany >> msg )
            {
                if( !msg.empty() )
                {
                    std::cout << msg << std::endl;
                    oldMsg = msg;
                }
            }
        }
       
        else
        {
            cout << "Nie udalo sie odbrac danych " << endl;
        }
    }
}


int main( int argc, char * argv[] )
{
   
    cout << "Klient" << endl;
    char data_wysylana[ 100 ];
    bool wyjscie = true;
   
    cout << "Wpisz adres ip : " << endl;
    string adres_ip_string;
    cin >> adres_ip_string;
   
    sf::Packet pakiet_wysylany;
   
    sf::Socket::Status status = socket.connect( adres_ip_string, 5000 );
   
    if( status != sf::Socket::Done )
    {
        cout << "Nie mozna polaczyc " << endl;
    }
    else if( status == sf::Socket::Done )
    {
        cout << "Polaczono" << endl;
        wyjscie = false;
        sf::Thread watekOdbioru( & odbierz_pokaz_dane );
        watekOdbioru.launch();
        while( wyjscie == false )
        {
            cin.getline( data_wysylana, 100 );
           
            pakiet_wysylany << data_wysylana;
            globalMutex.lock();
            if( socket.send( pakiet_wysylany ) != sf::Socket::Done )
            {
                cout << "Nie udalo sie wyslac danych " << endl;
            }
            globalMutex.unlock();
           
           
           
        }
    }
    return 0;
}

server :
C/C++
#include "stdafx.h"
#include <SFML/Network.hpp>
#include <string>
#include <iostream>

using namespace std;
const short PORT = 5000;
sf::TcpSocket socket;
sf::Mutex globalMutex;
void odbierz_pokaz_dane()
{
    static string oldMsg;
    while( true )
    {
       
        string msg;
        sf::Packet pakiet_odbierany;
       
        if( socket.receive( pakiet_odbierany ) == sf::Socket::Done )
        {
            if( pakiet_odbierany >> msg )
            {
                if( !msg.empty() )
                {
                    std::cout << msg << std::endl;
                    oldMsg = msg;
                }
            }
        }
       
        else
        {
            cout << "Nie udalo sie odbrac danych " << endl;
        }
    }
}

int main( int argc, char * argv[] )
{
   
    char data_wyslana[ 100 ];
    bool running = true;
   
    sf::TcpListener listener;
    listener.listen( PORT );
    sf::Packet pakiet_wysylany;
    if( listener.accept( socket ) == sf::Socket::Done )
    {
        cout << "Polaczono z : " << socket.getRemoteAddress() << endl;
    }
   
    sf::Thread watekOdbioru( & odbierz_pokaz_dane );
    watekOdbioru.launch();
    while( running )
    {
       
        cin.getline( data_wyslana, 100 );
        pakiet_wysylany << data_wyslana;
        globalMutex.lock();
        if( socket.send( pakiet_wysylany ) != sf::Socket::Done )
        {
            cout << "Nie udalo sie wyslac danych " << endl;
        }
        globalMutex.unlock();
       
       
    }
    return 0;
}
P-95468
DejaVu
» 2013-11-17 11:44:23
Nie widać w Twoim kodzie użycia setBlocking(false).
P-96408
« 1 »
  Strona 1 z 1