Advertisement

SFML network examples

Started by March 27, 2012 03:59 AM
0 comments, last by MARS_999 12 years, 8 months ago
Hello, I am lost on what I am missing to get my networking code working, to allow the server and client to send messages back and forth to each other... Do I need to setup a separate thread for each socket? e.g. one thread server one for client?

Looking to have someone edit what I would need to do to have this loop without having any issues... Right now I have to hit enter on both ends to see the results?


#include "stdafx.h"

bool running = true;
bool logged = false;

void SendMsgTcp(sf::TcpSocket& socket)
{
std::string s;
std::cout << "Enter Message: ";
std::cin >> s;

if(s == "exit" || s == "Exit" || s == "EXIT")
logged = false;

sf::Packet packet;
packet << s;
if(socket.send(packet) != sf::Socket::Done)
return;
std::cout << "Message sent to the client: \"" << s << "\"" << std::endl;
}
void RecieveMsgTcp(sf::TcpSocket& socket)
{
std::string s;
sf::Packet packet;
if(socket.receive(packet) != sf::Socket::Done)
return;
packet >> s;
std::cout << "Answer received from the client: \"" << s << "\"" << std::endl;
}

void runTcpServer(unsigned short port)
{
// Create a server socket to accept new connections
sf::TcpListener listener;

// Listen to the given port for incoming connections
if (listener.listen(port) != sf::Socket::Done)
return;
std::cout << "IP Address = " << sf::IpAddress::getPublicAddress().toString() << std::endl;
std::cout << "Server is listening to port " << port << ", waiting for connections... " << std::endl;

while(running)
{
sf::TcpSocket socket;
if(listener.accept(socket) == sf::Socket::Done)
{
// A new client just connected!
std::cout << "New connection received from " << socket.getRemoteAddress() << std::endl;
logged = true;
}
while(logged)
{
SendMsgTcp(socket);
RecieveMsgTcp(socket);
}
}
}
void runTcpClient(unsigned short port)
{
// Ask for the server address
sf::IpAddress server;
do
{
std::cout << "Type the address or name of the server to connect to: ";
std::cin >> server;
}
while (server == sf::IpAddress::None);

// Create a socket for communicating with the server
sf::TcpSocket socket;

// Connect to the server
if (socket.connect(server, port) != sf::Socket::Done)
{
std::cout << "Cannot connect to server " << std::endl;
return;
}
std::cout << "Connected to server " << server << std::endl;

while(running)
{
SendMsgTcp(socket);
RecieveMsgTcp(socket);
}
}

int main(int argc, char* argv[])
{
// Choose an arbitrary port for opening sockets
const unsigned short port = 5000;

// TCP, UDP or connected UDP ?
char protocol;
std::cout << "Do you want to use TCP (t) or UDP (u) ? ";
std::cin >> protocol;

// Client or server ?
char who;
std::cout << "Do you want to be a server (s) or a client (c) ? ";
std::cin >> who;

if (protocol == 't')
{
// Test the TCP protocol
if (who == 's')
runTcpServer(port);
else
runTcpClient(port);
}
else
{
// Test the unconnected UDP protocol
if (who == 's')
runUdpServer(port);
else
runUdpClient(port);
}

// Wait until the user presses 'enter' key
std::cout << "Press enter to exit..." << std::endl;
std::cin.ignore(10000, '\n');
std::cin.ignore(10000, '\n');

return EXIT_SUCCESS;
}
So far I have this simple example running and I can't figure out why the Client() can't loop to allow the server to send it's messages and allow me to output them each loop? I have to type something first before I can see the sent message from the server... Any ideas?


#include "stdafx.h"

const unsigned short PORT = 5000;
const std::string IPADDRESS("127.0.0.0.1");

bool quit = false;
std::ofstream fout("test.txt");

template<class T>
class SharedType
{
public:
std::vector<T> data;
sf::Mutex mutex;

SharedType(){}
~SharedType(){}
void Push(const T& t)
{
mutex.lock();
data.push_back(t);
mutex.unlock();
}
T Get(void)
{
T t;
mutex.lock();
if(!data.empty())
t = data.back();
mutex.unlock();
return t;
}
void Pull(std::vector<T>& v)
{
mutex.lock();
v = data;
data.clear();
mutex.unlock();
}
void Clear(void)
{
mutex.lock();
data.clear();
mutex.unlock();
}
};
SharedType<std::string> data;

void Server(void)
{
std::list<sf::TcpSocket*> clients;
sf::SocketSelector selector;
sf::TcpListener listener;

listener.listen(PORT);
selector.add(listener);

while(!quit)
{
if(selector.wait(sf::seconds(2.0f)))
{
if(selector.isReady(listener))
{
sf::TcpSocket* client = new sf::TcpSocket;
if(listener.accept(*client) == sf::Socket::Done)
{
clients.push_back(client);
selector.add(*client);
}
}
else
{
//receive messages from clients
for(std::list<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
{
sf::TcpSocket& client = **it;
if(selector.isReady(client))
{
sf::Packet packet;
std::string clientMsg;
if(client.receive(packet) == sf::Socket::Done)
{
packet >> clientMsg;
std::cout << "\nClient said: " << clientMsg << std::endl;
clientMsg.clear();
}
}
}
}
}
//send messages?
for(std::list<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
{
sf::TcpSocket& client = **it;
if(selector.isReady(client))
{
sf::Packet packet;
std::string s;
s = data.Get();
data.Clear();
if(!s.empty())
{
packet << s;
if(client.send(packet) == sf::Socket::Done)
{
std::cout << "\nMessage sent to client: " << s << std::endl;
}
}
}
}
}
}
void Client(void)
{
std::string s;
sf::Packet packet;
sf::TcpSocket socket;
socket.setBlocking(false);
while(true)
{
if(quit)
break;
socket.connect(IPADDRESS, PORT);
if(socket.getRemotePort())
break;
}
while(!quit)
{
if(socket.receive(packet) == sf::Socket::Done)
{
packet >> s;
std::cout << "\nThe server said: " << s << std::endl;
}
packet.clear();
s.clear();

s = data.Get();
data.Clear();
if(!s.empty())
{
packet << s;
if(socket.send(packet) == sf::Socket::Done)
{
std::cout << "\nMessage sent to server: " << s << std::endl;
}
}
packet.clear();
s.clear();
}
}
void GetInput(void)
{
std::string s;
std::cout << "\nEnter \"exit\" to quit or message to send: ";
std::cin >> s;
data.Push(s);
if(s == "exit")
quit = true;
}
int main(int argc, char* argv[])
{
sf::Thread* thread = 0;

char who;
std::cout << "Do you want to be a server (s) or a client (c) ? ";
std::cin >> who;

if(who == 's')
thread = new sf::Thread(&Server);
else
thread = new sf::Thread(&Client);

thread->launch();

while(!quit)
{
GetInput();
}
if(thread)
{
thread->wait();
delete thread;
}

std::vector<std::string> temp;
data.Pull(temp);
for(unsigned int i = 0; i < temp.size(); ++i)
fout << temp << std::endl;

return 0;
}

This topic is closed to new replies.

Advertisement