I am using MulticastSocket to receive UDP Multicast packets. How can I determine to which address such a packet was sent? With the methods provided, I am only able to determine the sender address.
Of course, I am the one who sets the To-Address when creating the listening socket, but can I really be sure about this? What about broadcast packets? What about packets that somehow end up here?
I really want to distinguish if the packet was REALLY multicast.
Thank you!
Update: Currently it seems like unicast packets just sent to that port also end up in the multicast sockets receive() :( Binding to devices also gives me no better results
I'm a bit fuzzy on the details but a multicast packet will have been sent to the ip/port combo you subscribed to (and this info will be in the packet, somewhere), assuming you managed to have a clear path of intermediary routers that understand multicast. If you want to make sure the multicastsocket is receiving from the right network interface, there's a bunch of functions to bind it to a specific interface.
I don't think you have any way of knowing if the packet was "really" multicast, i.e. someone could always forge one, since there's no real security built in.
Related
My professor gave me the task to realize a file transfer via UDP, which implements the protection mechanisms for reliability like as TCP (CRC check, correct packet order, ACK/NACK). I got some default classes from him (Socket & Channel) to simulate packet loss and delay on local machine. A packet loss when sending the packets is also simulated in its classes. However, this means that if an ACK is not sent correctly i can't notice it either, since an ACK from server to client is not confirmed with an ACK for an ACK from client to server.
I thought that packet loss can only happen when receiving packets.
Is it possible in real cases that an packet can be lost while sending without getting a code exception?
Greetings
Is it possible in real cases that an packet can be lost while sending without getting a code exception?
Easy. Simply send the packets from your application faster than the network interface can forward these. Of course any intermediate systems on the way (i.e. switches, routers) might also get overloaded and loose packets.
But at the end it does not actually matter how the packet is lost, i.e. if one the local system while sending, on the remote system while receiving or in between while forwarding. One simply cannot assume that a successful send will be matched by a successful recv.
IP packets contain the transport protocol (TCP, UDP, etc.) in their payload, and you lose IP packets all the time due to things like oversubscription at some point in the path. QoS, controls can also use something like RED that purposely discards packets in order to keep queues from filling and doing tail-drop. TCP can realize that TCP segments (not packets) are lost and resend them, but UDP has no mechanism to realize that its datagrams (not packets) are lost. UDP is a fire-and-forget protocol.
Let's say you want to make a real-time game, perhaps a 2D topdown game.
Things you would do in the game to keep it simple are:
Connect to the server
Move the player with the keys
Possibly press space bar to attack
Send a chat message
But what would happen if a datagram from any of these situations get lost?
What would you do?
1) Connecting to the server
If you send a UDP datagram to the server, the server would take your IP and port and then create a player
based on an ID it gives you, this it how it identifies you every time it receives a datagram from you.
But what if upon "connection" (not actually a connection, just a udp datagram that says 'make me a part of your server'), this initial datagram gets lost. Is it right to say that you would just resend it if after a certain period of time you did not receive a reply back from the server?
2) Moving the player/attacking
If at any time we move the player/press a movement key/attack key, we would send a keystroke
to the server telling it what key we pressed/released.
The server would then relay this to all the other clients.
But what if this keystroke datagram gets lost? Either upon client->server or server->clients.
Because keystrokes are happening all the time, is it efficient to just resend it all the time?
Or would we just ignore the fact that it got lost along the way because there's a chance that if you press a key again it will most likely make it the next time?
3) Sending a chat message
This would be something that MUST reach the server.
If it got lost along the way, after a certain period of time if we did not receive a reply from the other side/receiving end, do we re-send it?
TL;DR
Is it okay to just keep resending datagrams if we know after a certain period of time it did not reach?
And also, what about confirming if a datagram got successfully sent?
If client sends a chat message to the server, and the server receives it, should the server send a reply back to the client to confirm that it received it? What would happen if that reply got lost, what then?
Typically games using UDP have an application level protocol on-top so they can send some messages reliably and others not. If they wanted to send everything reliably they would be better off using TCP. However fast-paced games can not afford the delay TCP introduces and if the packet does get lost it's often too late to re-send it!
One way to implement reliable messages is, like you suppose, to send an ACKnowledgment reply that this particular packet was received - but what if that gets dropped you ask? The sender of the reliable packet typically re-sends a certain number of times (e.g. 3 times) and if no ACK is still received the sender then assumes the peer has dropped.
An excellent place for articles and game networking including how to minimise data sent is Shawn Hargreaves blog. (This is focused at C# XNA but the same logic applies irrespective of language/framework/platform).
Lastly:
Game network programming for fast paces games is hard. If your game is slow and/or turn based consider TCP and a lock-step approach which makes things considerably easier.
Don't re-invent the wheel, there are libraries that do things such as implementing reliability on top of UDP for when you need it, e.g. FalconUDP. Though this is a .NET one - I would like to see a Java port :)
If a datagram gets lost there is nothing the receiver can do, because he doesn't know about it. It's up to the sender to re-send, and it's up to you to design an ACK-based or NACK-based protocol so that the receiver knows when to do that.
Whether it is okay to just keep resending UDP datagrams depends on how the server treats the data in the datagrams. For example, if you resend a chat message, and the server receives both the original message and the resent message, does the server display the message twice? Note that you might end up resending even if the original message was received, because the reply to the original message might have gotten lost or delayed.
The best bet is to use TCP instead of UDP, since TCP has already solved all these problems for you. World of Warcraft, for example, started with TCP for chat and UDP for gameplay, and eventually converted to TCP for everything.
I have established an udp connection in my application, but the problem is that sometimes it does not receive code from UDP Server function. It happens many times so there is any way to fixed out this problem.
Thanks in Advance.
In short, no. When you use UDP there are no guarantees your message will reach the other side. Also, there is not really a "UDP connection", it is just discreet messages.
If you need a system which guarantees delivery, use TCP.
Also UDP packet may return twice.
Use TCP, Luke
I'm trying to make a multicast IP exclusive, i.e. it can be "locked" and when it is "locked", no more MulticastSocket can join it.
Is it possible? How do I do it? Here's some code to explain my case:
String multicastIP = "224.0.0.1"; //multicast IP to "lock" later
InetAddress group = InetAddress.getByName(multicastIP); //create group
MulticastSocket multicastSocket = new MulticastSocket(8800); //Create a MulticastSocket using port 8800
multicastSocket.joinGroup(group); //join the group
//This is the part where I want to "lock" the group/IP
Additional information:
I'm developing a network game where the single server to multiple clients broadcasting scheme is done via this method.
There was a time we created two servers (that happen to have the same multicast IP) and incidentally, the clients listen to both servers, receiving messages from both servers.
What we want to happen is to make the clients listen only to their respective servers.
Thanks! :D
Multicast won't do this for you.
You will have to examine each incoming packet when you receive it and match it against the (source address, source port) tuple the client is sending from.
Honestly I don't think there is much advantage to using muticast for this. One approach I have seen is to use multicast for service discovery, and then use unicast for the "real" protocol once you have discovered it.
Edit: For a LAN application, multicast may be acceptable. I would just be careful not to broadcast too much. (multicasts are essentially broadcasts to most switches; they are filtered out by the NIC rather than the network) That is, ideally make sure the server is the one sending the multicast traffic while the clients unicast updates to the server. (if every client multicasts state updates that all other clients can see, what's the purpose of having the server?)
I am looking for a way to not receive broadcast messages with DatagramSocket. The implementation seems to hide the destination address so I cannot use that as a filter. Setting setBroadcast seems to do nothing.
I have a socket bound in a local ip address but it still receives all the broadcast messages from the subnet.
InetAddress addr = InetAddress.getByName("1.2.3.4");
InetSocketAddress sockaddr = new InetSocketAddress(addr, 12345);
DatagramSocket socket = new DatagramSocket(sockaddr);
What would be the easiest way to filter the broadcast messages and only receive messages sent directly to my ip?
EDIT: The short answer is no. This question stemmed from an architecture where we had custom routing of UDP messages and some nodes in the subnet were not necessarily broadcasting or interested in the broadcasts. There were other issues with it and we ended up modifying the architecture a bit.
Here is a simple Java application using UDP packets that shows using the DatagramPacket class to send and received UDP datagrams and querying the various fields such as the sender's IP address. So if you can use the IP address of the sender as an indication as to whether the message should be processed or ignored, this should help you out.
If you are using class DatagramSocket, the UDP datagram received includes the header information and you can parse it out according to this DatagramSocket documentation. This article from wikipedia on User Datagram Protocol discusses the UDP datagram format and structure.
So the question is whether you can have a list of allowed senders of messages or some way to filter out not allowed senders.
Another option would be to provide some kind of identification information or signature in the datagram that will allow you to identify allowed datagrams versus those to be ignored. You do not mention the types of broadcasts but perhaps you can ignore anything that is less than a specified number of bytes or something similar. Or perhaps you can ignore any datagrams from a certain range of ports or allow only datagrams from a specific range of ports.