Salve!
Stavo giocando (termine usato prima dell'edit, "smanettare", che sulla Treccani risulta "Utilizzare il computer
con grande abilità e disinvoltura, sperimentando o modificando funzioni e programmi. "...)come mi capita nei momenti liberi con le SFML e i suoi socket(TCP/IP), ho creato un server che gestisce svariati client (usando 2 thread per ognuno, 1 input e 1 output) e un client con 2 thread aggiuntivi per i/o, prima o poi passo a thread & i/o asincrono, ma per ora sto pensando a divertirmi e quindi uso solo le cose che conosco.
Quello che le mie applicazioni fanno o dovrebbero fare è connettersi al server e dare gli input e le coordinate del mouse, poi il server li comunica a tutti i client e i client visualizzano un immagine su schermo che si muove seguendo le coordinate ricevute, quindi un immagine che segue il cursore del client (e visibile da tutti i client).
Ora, in locale funziona, e anche con hamachi: la scincronizzazione non è delle migliori (se posso considerarla sincronizzazione), all'inizio e in parti casuali dell'esecuzione l'input và lentamente e ci mette qualche secondo a ristabilizzarsi, ma riesco a vedere l'immagine che segue chiaramente il cursore.
Invece, con un account no-ip e un dns pubblico si connette normalmente ma i dati iniziano a essere corrotti, con piccole parti corrette (circa il 2% di tutto) e altre parti che sono caratteri casuali.
Esempio:
Quello che dovrebbe essere (e che risulta usando hamachi o ip locale)
Come risulta connesso al dns
Perchè?
I thread di I/O
ClieSide
void inputThread()
{
Socket::Status status;
char buffer[MAX_BUFFER];
size_t received;
bool connected = true;
client.socket.setBlocking(true);
while(connected == true)
{
status = client.socket.receive(buffer, MAX_BUFFER, received);
if(status != Socket::Done && status != Socket::NotReady)
{
cout <<"Disconnected." <<endl;
connected = false;
}
else if (status == Socket::Done && buffer[0] != '\0')
{
cout <<"Received " <<buffer<<endl;
inputString = buffer;
ISReadable = true; //La variabile booleana che controlla se l'input è leggibile dal main. Una volta letta viene riportata a false, nel main.
}
}
}
void outputThread()
{
stringstream ss;
string outputString;
char buffer[MAX_BUFFER];
Vector2i localPosition;
client.socket.setBlocking(true);
while(true)
{
localPosition = Mouse::getPosition(window);
outputString.clear();
ss.str(string());
ss << localPosition.x;
ss << "|";
ss << localPosition.y;
ss << "|";
if(Mouse::isButtonPressed(Mouse::Left)) //Serie di input non ancora utilizzata dal server.
ss << "t";
else
ss << "f";
ss << "|";
if(Mouse::isButtonPressed(Mouse::Right))
ss << "t";
else
ss << "f";
outputString = ss.str();
strcpy(buffer, outputString.c_str());
//cout <<buffer<<endl;
outputString = ss.str();
strcpy(buffer, outputString.c_str());
client.socket.send(buffer, MAX_BUFFER);
sleep(milliseconds(2));
}
}
Il server manda sempre i dati corretti. Buffer è corretto, lo stampo su schermo ogni volta prima di inviarlo
if(changeOString) //changeOString true = read OS1, changeOString false = read OS2
{
strcpy(buffer, outputString1.c_str());
cout <<buffer<<endl;
}
else
{
strcpy(buffer, outputString2.c_str());
cout <<buffer<<endl;
}
status = client[id].socket.send(buffer, MAX_BUFFER);
sleep(milliseconds(2));
[/code]
Cosa può essere?
P.s.
Perdonate quello che leggerete, l'ho fatto in una notte giusto perchè non avevo sonno e volevo programmare, non ho rispettato nessuno stile.
Esempio, tutti gli attributi delle mie classi sono
pubblici, prometto che appena risolvo i problemi principali creo un codice come si deve ahaha
Non carico tutto il codice di entrambe le applicazioni perchè sarebbero 600 righe di pugni agli occhi. Se serve per forza, proverò a fare del mio meglio per migliorare l'aspetto