I'm learning some UDP and am creating a Client - Server - Client chat program.
The way it's set up is that the Server runs first, and is always listening for some commands from the clients on port X.
The client, on the other hand, sends commands to the server on port X if it wants to log in or send a message, but it's listening on port Y for incoming packets from the server. The server, of course, sends messages on port Y, as well.
If Client A logs in (first thing user has to do), the server receives the client's username and then gets the client's IP based off of the packet it received, and stores both in a map with the username as the key.
When Client B logs in, the same process happens. Now Client A can send messages to client B (and vice versa), because both their usernames and IPs are stored in the server.
This all works fine when both clients are on the same machine, but once I try to run client B on a different machine, it seems as if the packet never reaches the server. There are no errors, the program doesn't crash, but the server never receives anything.
I tried a bunch of different IPs for the client to send to - one I got from running 'ipconfig' on my command line, another from googling "what is my ip address?", a third IP I got from printing out to the console InetAddress.getLocalHost() - all three of these IPs are different, and none seems to work.
On both machines I went to the firewall and allowed both port X and Y for UDP connections for inbound and outbound activities. This does not seem to help.
Here is my Server code:
public static void main(String args[]) throws IOException{
UDPServer SERVER = new UDPServer();
//calls the run() method
SERVER.start();
}
public UDPServer() throws IOException{
sock = new DatagramSocket(PORT_NUMBER, InetAddress.getLocalHost());
}
public void run(){
System.out.println("Waiting for Client");
while(true){
try{
//========================================================================================================
//Prepare the packet to receive data from client
//========================================================================================================
//Buffer (byte array) that will receive the client's data
byte[] buffer = new byte[512];
//Create a packet using the empty buffer and its length
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
//========================================================================================================
//Receive the packet from the client, execute the statement, and get the result
//========================================================================================================
//Receive the packet
sock.receive(packet);
System.out.println("Server: Received packet from Client");
//Extract the data
String fromUser = new String(packet.getData(), 0, packet.getLength());
//Parse data
String[] instructions = fromUser.split(separator);
//Add UserName and IP to tree
if(instructions[0].equals("LOGIN")){
System.out.println("Logged in!");
nameIPTree.put(instructions[1], packet.getAddress());
run();
}
//Send message to recipient and upload to DB
else if(instructions[0].equals("MESSAGE")){
//Create a string composed of the sender and the message
String toUser = instructions[1] + separator + instructions[3];
//Store the string in the buffer
buffer = toUser.getBytes();
//Make a new packet with the buffer, its length, the RECEPIENT'S IP (retrieved from tree, hence receiving user HAS TO BE LOGGED IN)
//and the port number the server uses
int add = 1;
packet = new DatagramPacket(buffer, buffer.length, nameIPTree.get(instructions[2]), PORT_NUMBER+add);
System.out.println("Sending packet from server to client at packet address: " + packet.getAddress());
//Send the packet
sock.send(packet);
System.out.println("Server: Sent result to Client: " + toUser);
}
}
catch (IOException /*| ClassNotFoundException | SQLException*/ e){
e.printStackTrace();
break;
}
}
System.out.println("Closing the socket");
sock.close();
}
}
Client code:
public String TalkToServer(String message){
try{
//========================================================================================================
//Create a datagram socket
//========================================================================================================
DatagramSocket sock = new DatagramSocket();
//========================================================================================================
//Connect & Send to server
//========================================================================================================
//Create a byte array called buffer that will hold the instructions to be sent to the server
byte[] buffer = message.getBytes("UTF-8");
//Get the IP address to which the packet will be sent - this is where the server is
InetAddress ipAddress = InetAddress.getByName("123.456.78.9");//here is where I tried the different IPs;
//Create a datagram packet which is composed of the buffer (message), its length, the IP address,
//and the port (matches with server's listening port) to send the data on
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ipAddress, PORT_NUMBER);
//I know these if statements do the same - it was for testing purposes
if(message.substring(0, 5).equals("LOGIN")){
System.out.println("Client: Logging in");
System.out.println("Packet's address is: " + packet.getAddress());
//Send the packet
sock.send(packet);
System.out.println("Client: Sent packet to Server\nSent: " + message);
sock.close();
return null;
}
if(message.substring(0, 7).equals("MESSAGE")){
System.out.println("Client: Sending message to server");
//Send the packet
sock.send(packet);
System.out.println("Client: Sent packet to Server\nSent: " + message);
sock.close();
return null;
}
}
catch(IOException e){System.out.print(e);}
return null;
}
}
And here is the client listener that's in my Main class:
public MainGUI() throws SocketException, UnknownHostException{
sock = new DatagramSocket(PORT_NUMBER+1, InetAddress.getLocalHost());
System.out.println("Client listening on ip: " + InetAddress.getLocalHost());
}
public void run(){
while(true){
try {
byte[] buffer = new byte[512];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
sock.receive(packet);
String fromUser = new String(packet.getData(), 0, packet.getLength());
//Parse data
String[] instructions = fromUser.split(separator);
txtAreaConvo.append(instructions[0] + ":\t" + instructions[1]+"\n\n");
} catch (IOException e) { e.printStackTrace(); }
}
}
Any help at this point would be wildly appreciated!!!
Thanks in advance,
Jona
Whenever I do socket programming, my first step is to get the packet communication working. I use a basic client - server implementation and simply send "Hello World", back and forth to make sure that I can run everything separately (not localhost). You may want to take a step-back from implementing the overall program and try to get the communication working before proceeding. This will probably show where your bug lies. With that being said, i'll try to guess where your problems are:
If your client - server communication is working, until you change to a different IP, then I would have to assume, like you did, that your are giving the wrong IP address/port number. Make sure the client are sending to the port X that the server is listening on. I suspect this isn't your problem; your problem is probably the IP you are giving. whatismyip.com, will give you your public IP address (the IP address you should use if your client is on a different network), ifconfig will give you your local IP Address, i.e. 192.168.X.X (the IP address you should use if the client is using the same network).
All in all, I would use my first suggestion. Take a step-back, and get a bare-basic server-client communication working before trying to solve your overall goal. If you need some basic client-server programs check out Java Socket Programing Examples. Once you get these working, I would continue onto solving your overall goal. This will help you narrow down your problem, and probably solve it.