SFML community forums
Help => Network => Topic started by: bugy on September 24, 2010, 06:30:40 pm
-
Hi,
A few days ago my friend wrote a post concerning using UDP. He was suggested that he should create Connected UDP on his own and also to start a new thread concerning that. So that's what I'm doing now.
We tried to google it, but we didn't find the solution.
This is the modified code. I combined it to a single program in hope that the variable IPClient stores some additional information about the client , but it doesn't seem so.
#include <SFML/Network.hpp>
#include <iostream>
using namespace std;
using namespace sf;
void server(int);
void client(int);
IPAddress IPClient;
int main()
{
cout << "Type: \'s\' to run server or \'c\' to run client." <<endl;
char input;
cin >> input;
if(input == 's')
{
server(0);
client(1);
}
else if(input == 'c')
{
client(0);
server(1);
}
system("Pause");
}
void server(int param)
{
SocketUDP Server;
if(param == 0)
{
if (!Server.Bind(10023))
{
cout << "Error" << endl;
}
}
else if(param == 1)
{
if (!Server.Bind(10024))
{
cout << "Error" << endl;
}
}
cout << "Server initialized." << endl;
IPAddress SenderIP;
unsigned short SenderPort;
sf::Packet Packet;
while (true)
{
sf::Socket::Status SocketStatus = Server.Receive(Packet, SenderIP, SenderPort);
cout << endl <<endl << "Socket status: " << SocketStatus << endl << "---------------" <<endl;
if(SocketStatus == sf::Socket::Done)
{
// Extract the message and display it
string message;
Packet >> message;
cout << "IP: " << SenderIP << endl << "Port: "<< SenderPort << endl << "Message: " << message<< endl;
IPClient = SenderIP;
return;
}
}
Server.Close();
}
void client(int param)
{
cout << "Client Initialized." << endl;
int ServPort;
IPAddress ServIP;
if(param == 0)
{
IPAddress ServIPBuff("here comes server IP"); // !!!
ServIP = ServIPBuff;
ServPort = 10023;
}
else if(param == 1)
{
ServIP = IPClient;
ServPort = 10024;
}
if (!ServIP.IsValid()){
cout << "Niepoprawny adres serwera" << endl;
}
SocketUDP Client;
string Message = "Hi, I'm a client !";
sf::Packet PacketToSend;
PacketToSend << Message;
cout << "Press Enter to send packet." <<endl;
getchar();
char input = getchar();
while(input == 10)
{
if (Client.Send(PacketToSend, ServIP, ServPort) != Socket::Done)
cout << "Pierdolony error!" << endl;
else
cout << "Message sent to server : \"" << Message << "\"" << endl;
input = getchar();
if(input == 'z') break;
}
Client.Close();
}
It simply listens for packets in server mode and resends a packet to the client after server receives one.
In client mode it sends a packet (or more) to a server and after you type 'z'. It starts listening for packets sent back from the server.
Everything works fine on LAN. But when I run the server mode on a real server (RPS with public ip) there occurs a problem. Server receives a packet from my computer (non-public, local ip) and than tries to send a packet back. Unfortunately it never is received by my computer.
So how should I modify it to have the effect of Connected UDP?
Bye
-
Excuse me, but you are doing very strange things here...
- When lauching the server, the server is never finishing, so client(1) will never be launched.
- Why stopping the clien to start a server (with z), when launching client ?
What is important is that UDP socket can send and receive, no need to be a server in order to receive packets.
What is meant by "connected UDP" is that your packets must manage a "virtual connexion" between server and client :
- ask to connect to the server
- if authorized, connect effectively
- when deconnecting, send it to the server in order the server deconnect the client
- etc...
So, I would modify your code as this (directly, no verification, there can be some errors ;) ) :
int main()
{
cout << "Type: \'s\' to run server or \'c\' to run client." <<endl;
char input;
cin >> input;
if(input == 's')
{
server();
}
else if(input == 'c')
{
client();
}
}
void server(int param)
{
SocketUDP Server;
if (!Server.Bind(10023))
{
cout << "Error" << endl;
return;
}
cout << "Server initialized." << endl;
std::vector<IPAddress> MyClients; // Important : the list of clients connected
IPAddress SenderIP;
unsigned short SenderPort;
sf::Packet Packet;
while (true)
{
if(Server.Receive(Packet, SenderIP, SenderPort) == sf::Socket::Done)
{
// Extract the message to know what to do
string message;
Packet >> message;
// Is a new client trying to connect ?
if (message=="CONN")
{
//... Verify that the client is not connected yet (in our client vector)
//... If not, verify we are not going over the MAX CLIENT count
//... If not, send to the client that the connection is ok (message="OK")
//... Add the IPAddress of the client in our vector
}
//A connected client is sending a message
{
//... Verify that the client is a connected one (in our client vector)
//... If not, do nothing or send it something to explain
//... If yes, ok, you can use the message
//... If the message is "DECO", then remove the client from the vector, because it just deconnect !
}
}
}
Server.Close();
}
By the way, you'll need something to close the server properly.
-
Thanks buddy. It really helped. Now I've got both way working transmission. :)
Bye