Search code examples
javaserverudpclient

UDP Chat Program different networks can't chat


I'm trying to make a chat program where the client and the server can chat with each other on different networks (not localhost) I'm currently faced with a problem that i don't know how to solve.

For some reason, the client and the server can't connect to each other, when i write a message to the server with the client, nothing pops up on the server. The tests were run on two different computers, on different networks (Mobile data and Ethernet)

I've used the public ip from my ethernet in the code, and portforwarded it with the matching port number in the code. The server is running on the portforwarded network.

This is my code:

CLIENT:


import java.io.*;
import java.net.*;
import java.util.Scanner;

public class ChatClient {

    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        DatagramSocket client = new DatagramSocket(7000);

        byte[] receivedData = new byte[1024];
        byte[] sentData;

        InetAddress address = InetAddress.getByName(" PUBLIC IP IS HERE, won't show it for obvious reasons ");

        while (true) {
            String message = scanner.nextLine();
            sentData = message.getBytes();

            DatagramPacket dp1 = new DatagramPacket(sentData, sentData.length, address, 7000);
            client.send(dp1);

            DatagramPacket dp4 = new DatagramPacket(receivedData, receivedData.length);
            client.receive(dp4);

            String receivedMessage = new String(dp4.getData());
            System.out.println(receivedMessage);
        }

    }
}

SERVER:


import java.io.*;
import java.net.*;
import java.util.Scanner;

public class ChatServer {

    public static void main(String[] args) throws IOException {
        DatagramSocket server = new DatagramSocket();
        Scanner scanner = new Scanner(System.in);

        byte[] receivedData = new byte[1024];
        byte[] sentData;

        while (true) {
            DatagramPacket dp2 = new DatagramPacket(receivedData, receivedData.length);
            server.receive(dp2);

            String storedData = new String(dp2.getData());
            System.out.println(storedData);

            InetAddress getIP = dp2.getAddress();
            int port = dp2.getPort();

            String sentMessage = scanner.nextLine();
            sentData = sentMessage.getBytes();

            DatagramPacket dp3 = new DatagramPacket(sentData, sentData.length, getIP, port);
            server.send(dp3);
        }

    }
}

The code worked when altered to localhost only.

Does anyone know what i'm doing wrong? Any replies are greatly appreciated.


Solution

  • Assuming the client connects to the server, the server needs to specify the port to listen and the client needs to specify IP and port of the server.

    Client:

    InetAddress address = InetAddress.getByName(" PUBLIC IP IS HERE"); 
    DatagramSocket client = new DatagramSocket();
    //...
    DatagramPacket dp1 = new DatagramPacket(sentData, sentData.length, address, 7000);//the port should be the publicly exposed port
    client.send(dp1);
    

    This connects to the server with specified IP and port.

    Server:

    DatagramSocket server = new DatagramSocket(7000);//port to forward
    

    This means that the server listens on port 7000 so it is available under that port.

    Aside from that, make sure the port forwarding works correctly. If you use UDP, you also need to configure it for TCP.

    Also note that UDP does neither confirm nor validate packages. If you want to have those features, you will need to either use TCP or implement those features by yourself.