1
Network / Re: Receiving data
« on: December 22, 2017, 06:16:02 pm »
Future Kerachi: There is a getline(std::cin,s); which will block your program, although I can not see any other big mistake, keep up the good work!
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
if(client->receive(packetReceive) == sf::Socket::Done){
if(packetReceive >> msg)
{
if(*it != msg && !msg.empty())
{
std::cout <<std::endl<< client->getRemoteAddress()<<": "<< msg << std::endl << "Me: ";
*it = msg;
}
}
}
Won't run, if I do not send data with the server to the client.#include <iostream>
#include <SFML/Network.hpp>
std::string msgSend;
//Since all the client constantly spamming data to the server I made this:
static std::vector<std::string> oldMessages;
//to keep track of the last sended messages, and don't handle them... (poor solution)
//Basicly it contains the client last message...
sf::Mutex globalMutex;
std::vector<sf::TcpSocket *> clients;
sf::TcpListener listener;
sf::SocketSelector selector;
bool quit = false;
void Receive_Packets(void)
{
while(!quit)
{
if (selector.wait())
{
if (selector.isReady(listener))
{
//If New client connected:
//- Create a new socket and add to the sockets list
//- Add new socket to the socket selector
//- Add oldMessages list a empty message, since the program won't allow the send the same message more times in row
//- Print new Client IP
sf::TcpSocket *client = new sf::TcpSocket;
//Add New Client
if (listener.accept(*client) == sf::Socket::Done)
{
clients.push_back(client);
selector.add(*client);
oldMessages.push_back("");
std::cout<<std::endl<<"New Client: " <<client->getRemoteAddress()<<std::endl << "Me: ";
}
//If listener can not accept the socket:
//- Print Clinet disconnected: Clinet IP
//- Delete newly created socket
//- Print new clients list size
else
{
std::cout<<std::endl<<"Client disconnected: "<< client->getRemoteAddress()<<std::endl;
client->disconnect();
delete(client);
std::cout<<"Clients: "<<clients.size()<<std::endl << "Me: ";
}
}
short messageIndex=0;
messageIndex=0; //To make sure...
for(sf::TcpSocket *client : clients)
{
if (selector.isReady(*client))
{
//IF I WON'T SEND SOMETHING, THEN THE RECEIVE PART WON'T RUN
//However if you delete the commend part, and run this code too, then it's will work
//but it will send data constantly, and eats about 20-25% processor power
/*
//Send Message
sf::Packet packetSend;
globalMutex.lock();
packetSend << msgSend;
globalMutex.unlock();
client->send(packetSend);
*/
sf::Packet packetReceive;
std::string msg;
//This iterator keeps track which client what sended last time
std::vector<std::string>::iterator it = oldMessages.begin() + messageIndex;
//Receive Message
if(client->receive(packetReceive) == sf::Socket::Done){
if(packetReceive >> msg)
{
if(*it != msg && !msg.empty())
{
std::cout <<std::endl<< client->getRemoteAddress()<<": "<< msg << std::endl << "Me: ";
*it = msg;
}
}
}
//IF the client disconnected:
//- Print Client disconnected: Clinet IP
//- Remove Client from the selector
//- Disconnecting the client
//- Delete client socket from the clients list (vector)
//- Delete the client last message from the oldMessages list (vector)
//- Print new clients list size
else if(client->receive(packetReceive) == sf::Socket::Disconnected){
std::cout<<std::endl<<"Client disconnected: "<< client->getRemoteAddress()<<std::endl;
selector.remove(*client);
client->disconnect();
clients.erase(std::remove(clients.begin(), clients.end(), client), clients.end());
oldMessages.erase(std::remove(oldMessages.begin(), oldMessages.end(), *it), oldMessages.end());
std::cout<<"Clients: "<<clients.size()<<std::endl << "Me: ";
}
}
++messageIndex;
}
}
}
}
//Get a row from the user and later on the Thread
//will send it to the clients
void GetInput(void)
{
std::cout<<"Me: ";
std::string s;
getline(std::cin,s);
if(s == "exit")
quit = true;
globalMutex.lock();
msgSend = s;
globalMutex.unlock();
}
int main()
{
const unsigned short PORT = 53000;
if(listener.listen(PORT) != sf::Socket::Done){
std::cout<<"Can not use "<<PORT<<" port"<<std::endl;
return 0;
}
selector.add(listener);
sf::Thread *thread = 0;
thread = new sf::Thread(&Receive_Packets);
thread->launch();
//MAIN LOOP:
//- Runs while the user doesn't type "exit"
std::cout<<"Server is ready."<<std::endl;
while(!quit){
GetInput();
}
std::cout<<"Server shut down..."<<std::endl;
//Close thread
if(thread)
{
thread->terminate();
delete thread;
}
//Delete all the sockets from the heap
for(int i=0;i<clients.size();++i)
delete clients[i];
}
Try to copy and paste it somewhere, it doesn't looks so great //Let say I'm sending data in every second
sf::Packet packetSend;
globalMutex.lock();
packetSend << msgSend;
globalMutex.unlock();
socket.send(packetSend);
//Then this part will run in every second, but I want it to run when data arraives to the server
//However I don't want it to run constantly, cuz that would eat a lot of processing power (about 20-25%)
std::string msg;
sf::Packet packetReceive;
socket.receive(packetReceive);
if ((packetReceive >> msg) && oldMsg != msg && !msg.empty())
{
std::cout << msg << std::endl;
oldMsg = msg;
}
Because this code right now runs while(!quit), which means it runs some million times per second. (of course it depends on hardware, but it not the thing what I would like to discuss here)sf::Packet packetSend;
globalMutex.lock();
packetSend << msgSend;
globalMutex.unlock();
socket.send(packetSend);
part constantly sending(spamming) data and it's eats a ton of processing power, however if I delete that part, then the socket.receive(packetReceive); simply won't run, even if I send data, from another client.imageName = layer["tiles"]["1"]["image"];
imageWidth = layer["tiles"]["1"]["imagewidth"];
imageHeight = layer["tiles"]["1"]["imageheight"];
//and other attributions...
//after that, you could load the image(s)...
texture.loadFromFile("wall.png");
walls.push_back(Wall(texture, 500.f, 490.f, 4)); //arguments: texture, position X, postion Y, direction 4 = down
for (Wall const &wal : walls)
wal.draw(window);
texture.loadFromFile("wall.png");
walls.push_back(Wall(texture, 500.f, 490.f, 4));
walls.push_back(Wall(texture, 563.f, 490.f, 4));
walls.push_back(Wall(texture, 626.f, 490.f, 4));
walls.push_back(Wall(texture, 500.f, 600.f, 4));
walls.push_back(Wall(texture, 563.f, 600.f, 4));
walls.push_back(Wall(texture, 626.f, 600.f, 4));
texture.loadFromFile("wall2.png");
walls.push_back(Wall(texture, 720.f, 540.f, 0));