Hi,
I'm working on a multiplayer internet game. I decided to use UDP protocol, as it's faster than TCP.

The problem is that UDP doesn't have an established server-client connection which makes it impossible for me to send data from server (with public ip) to a client (with non-public ip).

Using TCP I was easy, the client asked the server for a connection, than the server accepted it and data could be sent both sides. (the sever somehow was able to trace the client)

I have no idea how to get the same effect with UDP, although I read that udp is most suitable for network games.

To be more precise I'm using SFML network library, as I'm planing to write the game with it. Here is the documentation of the UDP socket:
http://www.sfml-dev.org/documentation/1.6/classsf_1_1SocketUDP.htm

Do you have any ideas how to solve the problem?

Recommended Answers

All 3 Replies

The same idea works for UDP too. Every IP packet indicates the source IP address, so you still know where it came from. The client sends a datagram to the server, the server stores the client's IP address somewhere, and from then on the server can send whatever datagrams it wants to that client.

The main difference here is that with TCP, the sender's address is sort of hidden by the "connection" abstraction; with UDP, you have to keep track of who's been calling.

The same idea works for UDP too. Every IP packet indicates the source IP address, so you still know where it came from. The client sends a datagram to the server, the server stores the client's IP address somewhere, and from then on the server can send whatever datagrams it wants to that client.

The main difference here is that with TCP, the sender's address is sort of hidden by the "connection" abstraction; with UDP, you have to keep track of who's been calling.

Well, here I send you the source of my simple program which uses UDP. 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 what do you think is the solution?

Program code:

#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();
}

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.

First thing to check is the client's address as it appears on datagrams sent to the server; see if it matches what you think its address should be. Your client machine may have a local IP address, but it also has to have a public IP address in order to send the datagram. If you're using a router, you may need to configure its firewall and port forwarding.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.