I'm using Netbeans IDE trying to make a UDP connection between client and server, it's a simple program that UDPClient send a String to UDPServer and the server capitalize the string and sends it back to the client.I made the client side and server side in a separated projects.
my class code for the client UDPClient :
package udpclient;
import java.io.*;
import java.net.*;
public class UDPClient {
public static void main(String[] args) throws IOException{
//get input from user
BufferedReader user_in = new BufferedReader(
new InputStreamReader(System.in));
//create udp socket connection
DatagramSocket socket = new DatagramSocket();
//creat buffers to process data
byte[] inData = new byte[1024];
byte[] outData = new byte[1024];
//get ip destination wanted
InetAddress IP = InetAddress.getByName("localhost");
//read data from user
System.out.println("Enter Data to send to server: ");
outData = user_in.readLine().getBytes();
/*
* make pkts for interaction
*/
//send pkts
DatagramPacket sendPkt = new DatagramPacket(outData, outData.length, IP, 9876);
socket.send(sendPkt);
//receive pkts
DatagramPacket recievePkt = new DatagramPacket(inData, inData.length);
socket.receive(recievePkt);
System.out.println("Replay from Server: "+recievePkt.getData());
}
}
and my server side class UDPServer:
package udpserver;
import java.io.*;
import java.net.*;
public class UDPServer {
public static void main(String[] args) throws IOException{
// TODO code application logic
//connection
DatagramSocket socket = new DatagramSocket();
//pkt buffers
byte[] inServer = new byte[1024];
byte[] outServer = new byte[1024];
//receive pkt
DatagramPacket rcvPkt = new DatagramPacket(inServer,inServer.length);
socket.receive(rcvPkt);
//display receive
System.out.println("Packet Received!");
//retrive pkt info to send response to same sender
InetAddress IP = rcvPkt.getAddress();
int port = rcvPkt.getPort();
//process data
String temp = new String(rcvPkt.getData());
temp = temp.toUpperCase();
outServer = temp.getBytes();
//send response packet to sender
DatagramPacket sndPkt = new DatagramPacket(outServer, outServer.length, IP, port);
socket.send(sndPkt);
}
}
make in count that the program runs normally and outputs no error. the server doesn't receive the packet at all , it didn't interact with the client. why does that happened ?
You haven't specified any listening port in your server so the server listen on a random available port.
Try with this on server side
DatagramSocket socket = new DatagramSocket(9876);
The problem is that your server code doesn't specify a port - it will listen to a random available port, whereas the client is sending to 9876. To correct this, use:
DatagramSocket socket = new DatagramSocket(9876, InetAddress.getByName("localhost"));
(If you're on a linux system) I'd highly recommend using netstat to debug this kind of code:
netstat -ln | grep 9876
will tell you if a process is listening to port 9876.
Another useful tool is netcat, which can be used to send and receive TCP and UDP:
nc -u localhost 9876
allows you to send messages over UDP to the server.
In your client code, you also need to turn the received bytes back into a string to get meaningful output.
Related
Here is my setup: On my home network a server is running on port SERVER_PORT. A port forwarding rule has been added to the router such that all incoming connections to SERVER_PORT will reach the server's machine. Somewhere else on the internet there exists a client who tries to send a UDP packet to the server and receive a packet back.
The server will receive the connection on SERVER_PORT but will send a packet back from a socket bound to a different (random) port.
The idea is emulating a listener socket just like the one used for TCP, and for each new connection allocating a new socket.
I have tested my program with clients that are connected to my home network, and outside the home network (cellular). The program didn't work either way.
The program does work though if I send a packet back using the server's original socket (the one that is bound to SERVER_PORT).
I am assuming this has something to do with my router's NAT table but I can't quite figure out the details.
My question is how can a packet be sent back from a different socket, other than the one that had been used for previous packets, and would I have had the same issue if the server was directly connected to the internet?
I wrote a small java program to demonstrate the issue:
Here is the server's code:
//create both sockets and a buffer
DatagramSocket serverSocket1 = new DatagramSocket(SERVER_PORT);
DatagramSocket serverSocket2 = new DatagramSocket();
byte[] buffer = new byte[512];
//receive a packet from serverSocket1
DatagramPacket packet1 = new DatagramPacket(buffer, buffer.length);
serverSocket1.receive(packet1);
System.out.println("received packet from: address = " + packet1.getAddress() + ", port = "+ packet1.getPort());
//send a packet from serverSocket2
DatagramPacket packet2 = new DatagramPacket(buffer, buffer.length, packet1.getAddress(), packet1.getPort());
serverSocket2.send(packet2);
System.out.println("sent packet back");
Here is the client's code: (note: SERVER_ADDRESS is set to my public ip)
//create a socket for the client and a buffer
DatagramSocket clientSocket = new DatagramSocket();
byte[] buffer = new byte[512];
//send packet1
DatagramPacket clientPacket1 = new DatagramPacket(buffer, 0, buffer.length, InetAddress.getByName(Server.SERVER_ADDRESS), Server.SERVER_PORT);
clientSocket.send(clientPacket1);
System.out.println("sent packet");
//receive packet2
DatagramPacket clientPacket2 = new DatagramPacket(buffer, buffer.length);
clientSocket.receive(clientPacket2);
System.out.println("received packet from: address = " + clientPacket2.getAddress() + ", port = "+ clientPacket2.getPort());
After running first the server and the the client I get the following output:
server:
received packet from: address = /107.107.56.147, port = 29098
sent packet back
client:
sent packet
My app is unable to receive the UDP packets when running in the emulator. UDP packets are sent by below java program on "localhost" over the port 49999.
DatagramSocket clientsocket;
DatagramPacket dp;
BufferedReader br;
InetAddress ia;
byte buf[] = new byte[1024];
int cport = 50000, sport = 49999;
clientsocket = new DatagramSocket(cport);
dp = new DatagramPacket(buf, buf.length);
br = new BufferedReader(new InputStreamReader(System.in));
ia = InetAddress.getLocalHost();
while(true)
{
Random rand = new Random();
String str1 = rand.nextInt(100) + "";
buf = str1.getBytes();
System.out.println("Sending " + str1);
clientsocket.send(new DatagramPacket(buf,str1.length(), ia, sport));
try{
Thread.sleep(100);
} catch(Exception e){}
}
Another java UDP server program running on the same localhost receives the packets fine. This means that the packets are sent to localhost:49999 correctly.
To forward the packets from localhost to the emulator, I did telnet redirect as below:
telnet localhost 49999
redir add udp:49999:49999
The UDP receiver in the app looks like this:
byte[] data = new byte[1400];
DatagramPacket packet = new DatagramPacket(data, 1400);
DatagramSocket socket = new DatagramSocket(49999);
socket.setSoTimeout(200);
try{
socket.receive(packet); ---->> This throws a SocketTimeoutException
} catch(SocketTimeoutException e){}
My understanding was that the telnet redirect should take care of forwarding the packets from my development machine's localhost:49999 to emulator's localhost:49999 so that the data is available on the DatagramSocket(49999). However it keeps throwing the SocketTimeoutException all the time.
It would be a great help to know what is the missing piece of the puzzle here.
After connecting to the localhost you may want to check that the port was actually asigned as intended with the command netstat -na in the cmd. It also might be worth a try to use the IP 127.0.0.1 instead.
I am trying to communicate to a network device via UDP protocol to read different values. The device writes values to port 11104. I just want to connect to device via UDP on this port and want to read the values. For this, i have written below code but it's not working. (I checked IP and Port number are correct).
public class GetDeviceResponseClass{
public static void main(String[] args){
int deviceport = 11104;
String deviceipaddress_str ="xxx.xx.xx.xxx";
byte[] rcvdata = new byte[1024];
InetAddress deviceipaddress = InetAddress.getByName(deviceipaddress_str);
DatagramSocket rcvsocket = new DatagramSocket();
rcvsocket.connect(deviceipaddress,deviceport);
DatagramPacket rcvpacket = new DatagramPacket(rcvdata,rcvdata.length);
rcvsocket.receive(rcvpacket);//here it is getting stuck
String response = new String(rcvdata,0,rcvpacket.getLength());
System.out.println("response = "+response);
rcvsocket.close();
}
}
I have a sample code as below and the socket is bound to IP 10.10.88.11 and port 9876. I tested with the 2 conditions with wireshark as below. Both PCs are in the same subnet.
Send UDP packet from the same pc (10.10.88.11) - UDP Server able to receive
Send UDP packet from another pc ( 10.10.88.10) - UDP Server unable to receive but Wireshark (at 10.10.88.11) able to capture the packets
I have searched the internet but can't find a solution for this. Is there anything i did wrong in creating the InetScoketAddress?
import java.io.*;
import java.net.*;
public class UDPServer {
public static void main(String args[]) throws Exception {
InetSocketAddress address = new InetSocketAddress("10.10.88.11", 9876);
DatagramSocket serverSocket = new DatagramSocket(address);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
System.out.println("Waiting to receive");
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
I believe Wireshark is able to grab packets before they are evaluated by the firewall, meaning that you will detect them but they will never reach the java app. Did you try deactivating your firewall ?
Client A
import java.io.*;
import java.net.*;
import java.util.*;
public class ClientA
{
final private static int PORT = 5005; // arbitrarily assigned port to use
public static void main(String args[]) throws
IOException
{
DatagramSocket socket = new DatagramSocket(PORT); // create new connection on that port
while (true)
{
byte buffer[] = new byte[256]; // data buffer
DatagramPacket packet = new DatagramPacket(buffer, buffer.length); // new packet containing buffer
socket.receive(packet); // look for packet
String clientBMsg = new String(packet.getData()); // get data from received packet
InetAddress address = packet.getAddress(); // get address of received packet
System.out.println("ClientB at " + address + " says " + clientBMsg);
buffer = null;
String msgString = "I'm ClientA, vegetables are fun";
buffer = msgString.getBytes(); // put String in buffer
int port = packet.getPort(); // get port of received packet
packet = new DatagramPacket(buffer, buffer.length, address, port); // create new packet with this data
socket.send(packet); // send packet back containing new buffer!
System.out.println("Message Sent");
socket.close();
}
}
}
Client B
import java.io.*;
import java.net.*;
public class ClientB
{
final private static int PORT = 5005; // arbitrarily assigned port - same as server
public static void main(String args[]) throws
IOException {
// if (args.length == 0) { // requires host
// System.err.println
// ("Please specify host");
// System.exit(-1);
// }
// String host = args[0]; // user defined host
DatagramSocket socket = new DatagramSocket(); // open new socket
String host = "localhost";//"86.0.164.207";
byte message[] = new byte[256]; // empty message
String msgString = "Hello, I'm client B and I like trees";
message = msgString.getBytes(); // put String in buffer
InetAddress address = InetAddress.getByName(host); // determines address
System.out.println("Sending to: " + address); // tells user it's doing something
DatagramPacket packet = new DatagramPacket(message, message.length, address, PORT); // create packet to send
socket.send(packet); // send packet
System.out.println("Message Sent");
message = new byte[256];
packet = new DatagramPacket(message, message.length);
socket.receive(packet); // wait for response
String clientAreply = new String(packet.getData());
System.out.println("ClientA at " + host + " says " + clientAreply);
socket.close();
}
}
I don't understand why this works over localhost but when I put my IP address in, it just sends the message and nothing is received.
Can anyone point me in the right direction here?
Thank you!
You should use DatagramSocket's bind method to bind it to your internet interface, otherwise it only listens on 127.0.0.1 or localhost. Like this:
DatagramSocket socket = new DatagramSocket(null);
socket.bind(new InetSocketAddress(InetAddress.getByName("your.ip.add.ress"),5005);
In case you are behind your router then your should listen on the local IP address given to you by the router and use port forwarding to this address in your router settings.
I can suggest using Socket Test tool with TCP and UDP Sockets:
http://sockettest.sourceforge.net/
I used it to trouble shoot issues with a 2-way socket program. You can end-to-end test your link with two SocketTest programs and the compare results, etc. Very useful.