Is it possible to detect a ping? I.e. device 1 pings device 2 and I want code that can run on device 2 that would detect whenever it is pinged by device 1.
The literal message used by the ping utility ("ICMP Echo Request") can be difficult to detect because it is customarily handled, and "eaten," by the network protocol-stack.
But if you simply want one computer or process to "broadcast" the fact that it's present (i.e. you don't need to receive a "reply," and you don't strictly care whether the message actually arrives at a particular place), the "UDP" network protocol might be just what you're looking for. Programming examples abound on the Internet. (And, right here, awaiting your "search.")
("UDP" is a datagram protocol, which so-to-speak "tosses a paper airplane out the window", whereas "TCP/IP" is concerned with bidirectional connections that are established, used, then torn-down.)
You can open a TCP or UDP socket on device 2 on some specific port and then try to connect on same port from device 1.
https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
You can decide what you want to use by reading about TCP and UDP.
https://en.wikipedia.org/wiki/Transmission_Control_Protocol
https://en.wikipedia.org/wiki/User_Datagram_Protocol
Related
When a connection of SerialPorts (RS232) is interrupted/disconnected, how could I detect it and report it to the user?
As can happen in any moment, I suppose I should use a separate thread.
My connection type is: send msg - recieve msg
RS232 does not detect the "state" of an physical connection. So I guess it is not possible to directly get an event in case of connect/disconnect. Probably the only way is to send something and detect if the answer is missing (or hearbeat or whatever...).
How much control do you have over the hardware or the remote device? You might be able to do something with the flow control lines: (i.e. if you are not using RTS/CTS flow control, but you can make your target device assert/deassert CTS, you might detect a change in CTS when the device is disconnected.) But be warned; this might work fine on one piece of hardware and not work on another due to hardware differences. In the general case, I agree with #MrD above that the most reliable/portable solution is to implement some heartbeat messaging (you send a message, wait for a response, like a TCP/IP PING), and generate a 'disconnect' event if you don't get a response within some timeout.
I have an application where multiple servers could exist. There are heaps of examples of how to use UDP to discover servers but it seems this only works with a single server.
What happens if multiple responses exist? Are they queued, corrupted (with UDP pitfalls) or something else ?
I would like to find out how to receive multiple responses from a UDP broadcast sent from an Android Device. If this isn't viable, is there any other recommended approach for multiple server discovery for Android clients..
Thank you
I would first send a packet to all servers you want to ask if they are there, then let all servers respond. Since you want to find out how to receive the packages, here is how i would do that:
long responseTimeout = 4000;
long start = System.currentTimeMillis();
while(true){
long now = System.currentTimeMillis();
if(now - start < responseTimeout){
datagramSocket.setSoTimeout((int) (responseTimeout - (now - start));
}else{
break;
}
try{
datagramSocket.receive(packet);
addOnlineServer(packet.getAddress());
}catch(SocketTimeoutException e){
break;
}
}
For a certain amount of time your android client should wait for responses, and add each ip of the received package to a list of online servers.
Sure some of the packages could get lost as you are using UDP, but that's what you get. If you want to be sure that no packages get lost, use TCP instead.
If you broadcast the message and the servers all return you should see all the responses as they come back.
However be aware that UDP is a potentially lossy protocol and makes no guarantees at all. Over a non-wireless LAN with decent switches it is pretty safe but as soon as it goes further than that (wireless, over multiple networks, etc) you can expect to lose at least some packets and any packet loss is a message loss on UDP.
The usual solution to this is to send each message a few times. So for example when you first start up you might broadcast at 1 second, 10 second, 30 seconds, and then every 10 minutes thereafter. This will find servers immediately, then sweep up any it missed fairly fast, and then finally detect any new ones that appear on the network.
I've not worked with this sort of system for quite a few years, but last time we did there was a single server acted as the center point. Everything when it started up broadcasted out to find the central server (retrying at increasing intervals until it found it) and when the central server started up it broadcasted out to find everything - retrying 3 times.
All communication after that was done by registering with that central server and getting the list of apps etc from there. The server essentially acted as a network directory so anything could get a list of anything else on the network by querying it.
You should be doing the following to receive and probably also send broadcast packets (which is what you are asking for):
Make sure that network mask is correct
When you bind the socket, be sure to bind it to INADDR_ANY
Set the socket's option to BROADCAST via setsockopt
Call the function sendto(..) with sendaddr.sin_addr.s_addr = inet_addr("your_interface_broadcast_address"), or call sento(..) several times for each interface with its broadcast IP address.
Call the function recvfrom(..), inside a while(..) loop, until you are certain "enough time has passed", usually 1 second should suffice on a LAN network
My application uses multicast capability of UDP.
In short I am using java and wish to transmit all data using a single multicast address and port. Although the multicast listeners will be logically divided into subgroups which can change in runtime and may not wish to process data that comes from outside of their group.
To make this happen I have made the code so that all the running instances of application will join the same multicast group and port but will carefully observe the packet's sender to determine if it belongs to their sub-group.
Warning minimum packet size for my application is 30000-60000 bytes!!!!!
Will reading every packet using MulticastSocket.receive(DatagramPacket) and determining if its the required packet cause too much overhead (even buffer overflow).
Would it generate massive traffic leading to congestion in the network because every packet is sent to everyone ?
Every packet is not sent to everyone since multicast (e.g. PIM) would build a multicast tree that would place receivers and senders optimally. So, the network that would copy the packet as and when needed. Multicast packets are broadcasted (technically more accurate, flooded at Layer2) at the final hop. IGMP assists multicast at the last hop and makes sure that if there is no receiver joining in the last hop, then no such flooding is done.
"and may not wish to process data that comes from outside of their group." The receive call would return the next received datagram and so there is little one can do to avoid processing packets that are not meant for the subgroup classification. Can't your application use different multiple groups?
Every packet may be sent to everyone, but each one will only appear on the network once.
However unless this application is running entirely in a LAN that is entirely under your control including all routers, it is already wildly infeasible. The generally accepted maximum UDP datagram size is 534 once you go through a router you don't control.
I'm using a ServerSocket on my server and Sockets that use ObjectIOStreams to send serializable objects over the network connection. I'm developing an essentially more financial version of monopoly and thus packets being sent and confirmed as sent/received is required. Do I need to implement my own packet loss watcher or is that already taken care of with (Server)Sockets?
I'm primarily asking about losing packets during network blips or whatnot, not full connection error. E.g. siblings move a lead plate between my router and computer's wi-fi adapter.
http://code.google.com/p/inequity/source/browse/#svn/trunk/src/network
Code can be found under network->ClientController and network->Server
Theoretically; yes. There is no way of giving 100 % theoretical guarantee that what is sent on the hardware layer, is received the same way on the receiving end.
Practically however, if you use TCP (Transmission Control Protocol) this stuff has already been taken care of; you won't loose any packets. (If you're using UDP on the other hand (User Datagram Protocol) it's another story, and it may very well be the case that you're loosing packets, or receiving them out of order).
Just looked briefly at your code, and it seems you're using multiple threads. If so you must be utterly careful with synchronization. It could very well be the case that it looks like a packet has been dropped, although, it is simply not handled due to a race condition in the program. (Keep in mind that the gui for instance, runs in its own thread.)
The best way to solve the synchronization, I think, is to put the network loop in a very small read/put-on-synchronized-queue loop, and pick up the received packets from the queue whenever you're sure no other thread will intervene.
My program needs to listen incoming socket connections (lets agree on port 8765), but it doesn't know which addresses it can bind on a particular machine.
Of, course, it could simply to listen to all of them, but it need to send to the client program over a different(slower) channel the addresses which it should try in order to rich me on port 8765.
So the flow is like this:
My program lisens on all available interfaces on port 8765
Finds out a list of inet4 adresses by which it can be possibly reached
(this step is the actual question)
Posts that address on a whiteboard (blogpost or something)
Interested clients try out all of them, to see using which one they can reach my program.
This is all is to be done in java ofcourse :)
NetworkInterface.getNetworkInterfaces()