Ageforce
Ageforce

Reputation: 19

How do i get the port and address of client without receiving data from it first?

I'm making a simple UDP chat program, and i would like the server to be able to send to the client without receiving data from it first. Normally, when it receives data from the client, the server gets the IP and port of the client, so it can communicate with it.

My server code:

package com.ageforce;

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

public class ChatServer {
    DatagramSocket server;
    byte[] receivedData = new byte[1024];
    Scanner scanner = new Scanner(System.in);
    byte[] sentData;
    DatagramPacket dp2 = new DatagramPacket(receivedData, receivedData.length);

    public ChatServer() throws SocketException {
        server = new DatagramSocket(7000);
    }

    public static void main(String[] args) throws SocketException {
        ChatServer cs = new ChatServer();

        Thread receiveMessage = new Thread(() -> {
            while (true) {
                try {
                    cs.server.receive(cs.dp2);

                } catch (IOException e) {
                    e.printStackTrace();
                }

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

        Thread sendMessage = new Thread(() -> {
            while (true) {
                String sentMessage = cs.scanner.nextLine();
                cs.sentData = sentMessage.getBytes();

                // This is the area of the code where the server gets IP and port of client from the received data. I'd like this to be changed.
                InetAddress getIP = cs.dp2.getAddress();
                int port = cs.dp2.getPort();

                DatagramPacket dp3 = new DatagramPacket(cs.sentData, cs.sentData.length, getIP, port);
                try {
                    cs.server.send(dp3);

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });


        sendMessage.start();
        receiveMessage.start();
    }
}

Is it possible to do this? Any reply is greatly appreciated.

Upvotes: 0

Views: 121

Answers (2)

rzwitserloot
rzwitserloot

Reputation: 103913

In order to send an UDP message to something, you need to know the IP and port number to send it to. How? Well, you tell me.

The way your protocol works right now is that the clients know your hostname (which they let their system turn into an IP automatically), and the port number is hardcoded in the client app. The server knows which IP and port to send data back to by checking the 'sender' IP/port when it receives a call.

If you don't like your current protocol you'll need to figure out a different way to answer this question.

Even if you find a way, you'll find that this is mostly useless. The vast majority of end-users intentionally do not have a so-called publically routable IP address. You cannot reach them by design. In your current protocol, that IP/port combo you send back to isn't really the sending computer at all. It's some router, for example the router in their home. That router saw the outgoing UDP packet and is remembering for a while: Any traffic coming in on that port is supposed to go to that computer in this house.

Short of completely crazy stuff such as 'hole punching' (which skype used for a while, not sure if they still do, it's a complicated hack that doesn't always work and is surely not what you want here - you can search the web for that term), there's simply nothing you can do here. end-user systems aren't servers and cannot be reached like this.

Your run-of-the-mill chat apps will always have clients ping the server and then just keep that connection open as long as they can.

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 181932

How do i get the port and address of client without receiving data from it first?

UDP does not afford that possibility. It is a connectionless protocol, so the server doesn't even know that there is a client until it receives a message from it.

You could conceivably create some kind of preliminary application-level protocol whereby the client announces itself to the server before sending it any chat data, but nothing of the sort is part of UDP itself, and if that's something you want then you should consider using TCP instead, which does have a built-in concept of establishing a connection before sending any data.

Upvotes: 2

Related Questions