UDP client not reachable in Java - java

I am running a simple UDP Java Server, which collects IP and Port of Client when connected, store information in Database.
Client is still listening to server. Server stops.
Later, server want to reuse the database information, to reach the client; and as the client is still listening to same port of server, I guess client should receive the communication.
I am new to UDP, please let me know the way to achieve the above objective. Thank you.
Let me rephrase the question as I did try the ways suggested by members of Stackoverflow.
The client can be contacted by server within a short timespan, but after say 10 mins the client is unreachable; although it appears client is ready to listen to server for all the time but the server cannot reach client even if tried for several time. What could be cause for this? please let me know the way to deal with this

I think you are a bit confused regarding the UDP protocol (RFC 768). I think it would be helpful to review the UDP protocol to understand the differences between UDP and TCP.
Regarding your specific problem, it is difficult to know what is your exact problem without any type of code. There is a Client-Server in UDP example available in the sun tutorials.

UDP is sessionless, so I guess it should indeed work.
It would go something like that:
// Client:
socket = new DatagramSocket();
DatagramPacket req = new DatagramPacket(data, data.length, serverAddress, serverPort);
socket.send(req);
DatagramPacket resp = new DatagramPacket(new byte[MAX_RESP_SIZE], MAX_RESP_SIZE);
socket.receive(resp);
// Server:
DatagramSocket socket = new DatagramSocket(port);
while (!stopped) {
DatagramPacket req = new DatagramPacket(new byte[MAX_REQ_SIZE], MAX_REQ_SIZE);
socket.receive(req);
saveToDatabase(req.getAddress(), req.getPort());
}
socket.close();
// Then later:
DatagramSocket socket = new DatagramSocket(port);
// retrieve clientAddr and clientPort from database
DatagramPacket resp = new DatagramPacket(data, data.length, clientAddress, clientPort);
socket.send(resp);
socket.close();

Related

Sending DatagramPacket with no internet connection - Android

I'm using the following code to send DatagramPacket to a given address:
InetAddress address = InetAddress.getByName(anIPAddress);
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(packetBytes, packetBytes.length,
address, port);
socket.send(packet);
socket.close();
It works fine, but how come this code does not throw any Exception when there's no internet connection available?
I turn off both Wi-Fi and mobile data, and this code still gets executed without any errors.
Is there a way to ensure that the packet is actually sent?
(i don't care if it's reached the destination or not, i'd just like to make sure it is sent)
You can use NetworkInterface.getNetworkInterfaces(); to check what interfaces are available.
Then you can check with ni.isUp().
Enumeration<NetworkInterface> nets=NetworkInterface.getNetworkInterfaces();
for(int i=0; nets.hasMoreElements(); ++i) {
NetworkInterface ni=nets.nextElement();
if (ni.isUp() && !ni.getName().equals("lo")) {
//ni is not local
break;
}
}
Connect the datagram socket to the destination. Then after a few sends you may get an exception. If the datagram socket isn't connected there's an error routing issue which I cannot remember offhand: I'll edit it in when au get a chance to look it up.
And yes I know UDP is a connectionless protocol. But you can still connect a UDP socket.

Java UDP DatagramSocket stops receiving

I have a DatagramSocket where I'm receiving in a loop and it eventually just stops receiving packets. I send the server a hello message that establishes the connection. Then I start reciving packets as expected. Eventually it just stops receiving.
The sending server has verified that they are still sending packets to the same address via tcp dump but eventually this code hangs on the receive call.
Is there anything that would cause the socket to stop receiving?
String hello = "hello";
InetAddress IPAddress = InetAddress.getByName("serveraddress");
DatagramPacket outboundPacket = new DatagramPacket(hello.getBytes(),hello.getBytes().length, IPAddress, 54321 );
DatagramSocket registerSocket = new DatagramSocket(61646);
registerSocket.send(outboundPacket);
int count = 0;
while(!done){
count++;
byte[] inboundData = new byte[1368];
DatagramPacket inboundPacket = new DatagramPacket(inboundData,inboundData.length);
System.out.println(registerSocket.getPort());
System.out.println(registerSocket.getLocalPort());
//Eventually locks up here after hundreds of successful receives
registerSocket.receive(inboundPacket);
byte[] data = inboundPacket.getData();
String test = new String(data, "ISO-8859-1");
System.out.println(test+"---"+count);
}
registerSocket.close();
If you're behind NAT, the mapping will time out if there's no outbound traffic for too long. Make sure to send an outbound datagram every few minutes to keep the mapping active in the router.
Not clear from the question, whether you work with several DatagramSockets inside one process: This would be non-trivial. See Java: Receiving an UDP datagram packet with multiple DatagramSockets
Unless using multicast, a newly created datagram socket will inherit the process' receiving cursor and clamp
the existing one from receiving.

Using same address and port for accepting and connecting in Java

(This might have been asked a thousand times, but I do not get it straight.)
Suppose I have the following snippet:
InetAddress localAddress = InetAddress.getByName("192.168.1.10");
int localPort = 65000;
InetAddress targetAddress = InetAddress.getByName("192.168.1.20");
int targetPort = 65000;
// Create a new serversocket
ServerSocket ss = new ServerSocket(localPort, 50, localAddress);
// Wait for an incoming connection...
Socket acceptedSocket = ss.accept();
// Do something with the accepted socket. Possibly in a new thread.
Set up new connection...
Socket socket = new Socket(targetAddress, targetPort, localAddress, localPort);
// Write something to the socket.
Now can I use the same address and port for both accepting an incoming connection and connecting to an address? If it can, then how? If not, then why not? According to this post, ports can be shared, so it shouldn't be a problem.
How does it work?
You can only establish a connection by having the connecting socket use the same address and port. (Ignoring the use of multi-homed servers)
A single connection is a unique combination of both the source address+port and destination address+port, so you can have the same destination if you have a different source.
In other words, can you write server program that that contains client connecting to itself? The answer is yes, surely. All integration tests do this running in-process server and connecting to it.

How to run tcp and udp on a single port at same time?

I have a situation like I have to run UDP and TCP both on a single port at a time. This is because in my application at any time anyone can call for any protocol. So I need to continously check the incoming request and serve the request. Can anyone pls help me to get rid of this situation in java?
You can't check whether a request is TCP or UDP. Instead you add a listener which is TCP and a listener which is UDP. IMHO UDP is more useful if you use a broadcast or multi-cast address.
e.g.
ServerSocket ss = new ServerSocket(12345);
DatagramSocket ds = new DatagramSocket(12345);
or
ServerSocket ss = new ServerSocket(12345);
DatagramSocket ds = new MulticastSocket(new InetSocketAddress("224.224.1.1", 12345));
In both cases, tcp connections go to the ServerSocket and udp packets go to the DatagramSocket

Connect two computer over http without public IP

I'll like to computers/clients to connect directly to each other in the case where one or both of them haven't got a public IP. I guess this could be done with a server as a middle man. The connection established in the end must be direct traffic between the clients. How is this possible, and what is the technic called?
I'll really like to see some code fx in Java.
Thanks
If port forwarding is not an option, there is a mostly-reliable technique you can use with UDP traffic called NAT traversal. It requires a middle-man server to act as a rendezvous point, but after the initial set-up all traffic will be endpoint-to-endpoint.
This will not work in all cases; it depends on how the various NAT layers map external endpoints to internal entpoints.
TCP NAT traversal is very difficult to implement and has an extremely low chance of even working.
(I have successfully used UDP NAT traversal to establish an OpenVPN connection between two computers at different universities, both behind several NAT layers!)
You will propably have to use hole punching (TCP or UDP) if both parties are behind NAT. Something like this:
socket = new DatagramSocket(port);
volatile boolean connectionEstablished = false;
volatile boolean reveivedSomething = false;
Sender-Thread:
while (!connectionEstablished) {
byte[] buf = new byte[256];
buf[0]=reveivedSomething?1:0;
DatagramPacket packet = new DatagramPacket(buf, buf.length,
otherpcpublicaddr, otherpcsport);
socket.send(packet);
Thread.sleep(500);
}
Receiver-Thread:
while (true) {
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
reveivedSomething=true;
if (buf[0]==1) {
connectionEstablished=true;
break;
}
Thread.sleep(500);
}
(you would have to do this on both PCs and to exchange IPs and ports using some reachable server as long as they aren't static)
I don't know of a Java fix, but you could use a dynamic dns service to re-route the traffic into the non-public ip. I think they use a client that keeps track of the public client IP that is assigned by their ISP, and reports it to the service, which then updates their host table. There may also be some configuration needed on each system's routers, in order to forward the public request into the private ip.
There would be several techniques used to perform this, port forwarding, NAT, Dynamic DNS, etc

Categories