Sending UDP packet to everybody in a LAN? - java

Is there a way to send a UDP packet inside a LAN so that every machine receives it? (Of course no guarantees because its UDP).
Like, sending a request "Hello, anybody out there?" and then listening for a response?
I got no problem with sending and receiving, just want to know if there's a way other than trying out every IP address possible...
Edit: This is what I use at the moment:
...
multicastSocket = new MulticastSocket();
multicastSocket.setBroadcast(true);
broadcastGroup = InetAddress.getByName("255.255.255.255");
// multicastSocket.joinGroup(broadcastGroup);
...
The last line of code is commented out because it throws an exception. Now I've read that sending a packet to 255.255.255.255 is "deprecated since years" and most likely won't work on many LANs. Also, I'm not sure if I even need a MulticastSocket for this or if a normal DatagramSocket would work as well. But anyway, what would be the preferred way to send a UDP broadcast nowadays?

Well, I found it out by myself:
Just open a MulticastSocket and use joinGroup on any IP between 224.0.0.0 and 239.255.255.255. Of course everything related to that multicast group needs to receive on the same multicast IP.
I did it for sending AND receiving, however, I think you only need it when receiving messages. When you want to broadcast a packet to everybody in the IP group, just send it to the IP you selected.
You should also do setBroadcast(true); to allow broadcasting for certain (?) systems.

Technically speaking you actually need to broadcast the message. Basically you need MulticastSocket, this kind of socket is used on the client-side to listen for packets that the server broadcasts to multiple clients.
Here is the java tutorial to help you achieve that:
http://docs.oracle.com/javase/tutorial/networking/datagrams/broadcasting.html

Related

How to use Java MulicastSocket (UDP)?

I develop client-server application, working in real-time. Server and clients exchanges by small messages, so I choose UDP for my architecture (as suggested in many articles in network).
It's not a problem for me to use default java's DatagramSocket/DatagramPacket for orginizng all things as I want, but when I read documentation I see the "MulticastSocket" opportunity.
But it is completely unclear for me: How MutlicastSocket at the user side will know where to connect? (public IP/port of the server). Really, as this shown at this official java tutorial.
MulticastSocket creates like:
MulticastSocket socket = new MulticastSocket(4446);
InetAddress group = InetAddress.getByName("203.0.113.0");
socket.joinGroup(group);
and there is NO any specification about public server IP and port.
What is "203.0.113.0"? It is possibles that tones of applications send something to that address in web, isn't it?
When I create client in regular (not Multicast) way I use something like:
DatagramSocket outputClientSocket = new DatagramSocket();
DatagramPacket outputPacket = new DatagramPacket(new byte[512],512,InetAddress.getByName("94.***.89.***"),9898);
...
where "94.???.89.???" is my server's public IP address, and 9898 is port of my server, that listens it. Like that:
DatagramSocket serverInputSocket = new DatagramSocket(9898);
DatagramPacket inputServerPacket = new DatagramPacket(new byte[512],512);
serverInputSocket.recieve(inputServerPacket);
and after recieving something I can establish connection with client, and answer something for him, like that:
DatagramSocket socketForSpecificClient = new DatagramSocket();
InetAddress realClientAddress = inputServerPacket.getAddress();
int realClientPort = inputServerPacket.getPort();
DatagramPacket packetForSpecificClient = new DatagramPacket(new byte[512],512,realClientAddress,realClientPort);
socketForSpecificClient.send(packetForSpecificClient);
This approach works well, even if client has no public IP.
It is absolutely clear way of establishing connection for me, but I can't understand for what purposes MulticastSocket should be used?
Multicast is in IPv4 usually not working across network segments. If your application is supposed to work on the internet (and not e.g. just within an intranet under your control), you can not base your communcation on multicast.
Edit: Here are some further resources on the subject:
Wikipedia on IP multicast:
multicast services are generally not available to the average end-user
Other Stackoverflow question 'UDP Multicast over the internet?':
In general this is not possible since multicast packages aren't routed.
Discussion on hardforum.com 'Does multicast work over the itnernet(sic)?':
ISPs filter mutlicast you can't join a multicast stream over the internet.
These are just a few of the first hits when googling for 'using multicast over the internet'.
The address range 203.0.113.0/24 is reserved for use in 'documentation and example code' so the address in the example, 203.0.113.0, does not point to a real endpoint.
If you need a real, public multicast address and are connected through an ISP with multicast support, you have to obtain one from the IANA registry. You are right that anyone can send (potentially bogus) data to that IP address, but you have exactly the same problem with unicast addresses. If you provide a service on a unicast address, anyone can connect to that address and send data to it.
Quoting the paragraphs from the book Java Network Programming for framing the answer :
How MutlicastSocket at the user side will know where to connect?
(public IP/port of the server)?
What is "203.0.113.0"? It is possibles that tones of applications send
something to that address in web, isn't it?
Firstly, you should generally use IP-Address lying between 225.0.0.0 to 238.255.255.255 for creating a new multicast group.
When a host wants to send data to a multicast group, it puts that data in multicast datagrams, which are nothing more than UDP datagrams addressed to a multicast group. Multicast data is sent via UDP.
A multicast address is the shared address of a group of hosts called a multicast group. IPv4 multicast addresses are IP addresses in the CIDR group 224.0.0.0/4 (i.e., they range from 224.0.0.0 to 239.255.255.255).
A multicast group is a set of Internet hosts that share a multicast address. Any data sent to the multicast address is relayed to all the members of the group. Membership in a multicast group is open; hosts can enter or leave the group at any time. Groups can be either permanent or transient. The IANA is responsible for handing out permanent multicast addresses as needed.
Multicasting sends data from one host to many different hosts, but not to everyone; the data only goes to clients that have expressed an interest by joining a particular multicast group. In a way, this is like a public meeting. People can come and go as they please, leaving when the discussion no longer interests them. Before they arrive and after they have left, they don’t need to process the information at all: it just doesn’t reach them. On the Internet, such “public meetings” are best implemented using a multicast socket that sends a copy of the data to a location (or a group of locations) close to the parties that have declared an interest in the data.
In the best case, the data is duplicated only when it reaches the local network serving the interested clients: the data crosses the Internet only once. More realistically, several identical copies of the data traverse the Internet; but, by carefully choosing the points at which the streams are duplicated, the load on the network is minimized. The good
news is that programmers and network administrators aren’t responsible for choosing the points where the data is duplicated or even for sending multiple copies; the Internet’s routers handle all that.
To receive data that is being multicast from a remote site, first create a MulticastSocket with the MulticastSocket() constructor. As with other kinds of sockets, you need to know the port to listen on. This code fragment opens a MulticastSocket that listens on port 2300:
MulticastSocket ms = new MulticastSocket(2300);
Next, join a multicast group using the MulticastSocket ’s joinGroup() method:
InetAddress group = InetAddress.getByName("225.2.2.2");
ms.joinGroup(group);
This signals the routers in the path between you and the server to start sending data your way and tells the local host that it should pass you IP packets addressed to the multicast group.
Once you’ve joined the multicast group, you receive UDP data just as you would with a DatagramSocket .
It is possibles that tones of applications send something to that
address in web, isn't it?
One would face the same problem even in case of unicast communication if the address is known on which the service is provided.

IP headers in Java

I am testing the behaviour of some client software, and need to write some software that emulates router-like functionality, preferably using something simple like UDP sockets. All it needs to do is receive the packet, alter the time to live, and send it back. Is this possible in regular Java? Or do you do something like the following:
Listen on Socket A
For EACH udp packet received, open a NEW socket, set time to live on that socket, and send it back (or this isn't possible/efficient?)
Receiver gets packet with altered values that appear like it has traversed some hops (but in reality hasn't)
So two approaches may be possible - editing the recieved packet directly (and then simply sending back), or constructing a new packet, copying the values from the original one and setting the appropriate headers/socket options before sending it out.
EDIT: the 'router' does not do any complex routing at all such as forwarding to other routers... it is simply decrements the t-t-l header field of the received message and sends the message directly back to the client.
Please refer API of Socket and ServerSocket class. Most of the server implementation for variety of protocols does accept packets at standard port like 80 and send response using some ephemaral port.

Java DatagramSocket setting keep-alive option

I'm trying to create a datagramsocket with and datagrampacket to send with the keep-alive option. I'm confused about how to set this though. Is there a simple way to do it like datagramsocket.setKeepAlive(true); ?
EDIT: Sorry, I meant setting the time to live of a packet. Is there a way I can set it so if it isn't received, it will stay until it is received?
UDP is what's called connectionless protocol, i.e. no connection is established, you just send packets to an ip address/port tuple. Since there is no connection, there is nothing to keep alive.

Some UDP socket programming questions I am confused about

What would happen if change both clientSocket and serverSocket to “mySocket”?
Can the client send a segment to server without knowing the server’s IP address and/or port number?
Can multiple clients use the server?
From my notes, on page 20 : http://www.cs.ucc.ie/~cjs/teach/cs2505/02-app-layer-b.pdf . Kind of confused with these.
I assume if you change both client and serverSocket to mySocket then nothing would happen, since it would only be a variable name change( I assume ).
And I assume the client can't send a message without know the IP address/port no?
And that multiple clients cannot use the server since that would require threading?
(1) Since I see no reference to mySocket other than the one in the question I would say your answer seems right.
(2) The address/port are obviously necessary. However this could be a trick question in that client could call connect() on the socket. With UDP, connect() the kernel keeps track of the address passed in the call as the peer of the socket. The socket could then just call write() or send() rather than having to use sendto(). Still, calling connect would still require the address/port in the first place so who knows what they are getting at.
(3) There is no "connection" in UDP. Many clients could send to the server. The server can get the address of the individual clients from its recvfrom and then turn around and use that address in its sendto.

How to distinguish between two different UDP clients on the same IP address?

I'm writing a UDP server, which is a first for me; I've only done a bit of TCP communications. And I'm having trouble figuring out exactly how to distinguish which user is which, since UDP deals only with packets rather than connections and I therefore cannot tell exactly who I'm communicating with.
Here is pseudocode of my current server loop:
DatagramPacket p;
socket.receive(p); // now p contains the user's IP and port, and the data
int key = getKey(p);
if(key == 0) { // connection request
key = makeKey(p);
clients.add(key, p.ip);
send(p.ip, p.port, key); // give the user his key
} else { // user has a key
// verify key belongs to that IP address
// lookup the user's session data based on the key
// react to the packet in the context of the session
}
When designing this, I kept in mind these points:
Multiple users may exist on the same IP address, due to the presence of routers, therefore users must have a separate identification key.
Packets can be spoofed, so the key should be checked against its original IP address and ignored if a different IP tries to use the key.
The outbound port on the client side might change among packets.
Is that third assumption correct, or can I simply assume that one user = one IP+port combination? Is this commonly done, or should I continue to create a special key like I am currently doing?
I'm not completely clear on how TCP negotiates a connection so if you think I should model it off of TCP then please link me to a good tutorial or something on TCP's SYN/SYNACK/ACK mess.
Also note, I do have a provision to resend a key, if an IP sends a 0 and that IP already has a pending key; I omitted it to keep the snippet simple. I understand that UDP is not guaranteed to arrive, and I plan to add reliability to the main packet handling code later as well.
UDP packet headers have a source port, which is generally used as the reply port. If not used, it should be zero, and then it is up to the higher level protocol to figure out how to coordinate request-response activity with multiple clients.
* The outbound port on the client side might change among packets.
Is that third assumption correct
Not if the client keeps using the same outbound socket. Sending the first datagram will cause a local bind, so the socket will be on a fixed local port from then on.
Your questions are just the tip of the iceburg WRT laundry list of issues you need to be aware of when using UDP. You should expect NAT routers to fail to provide any meaningful forwarding of a UDP protocol you design. TCP works because the routers understand the TCP state machine and store connection state of each session so they know how to forward it. They will have no idea how your custom UDP protocol works. NAT devices include specific protocol handlers for well known UDP applications.
If a sender is bound to a source port and or interface the senders source ports remain constant until unbound.
With UDP you can bind both peers to a known source port for (dst) incoming and or (src) outgoing messages. For client/server applications you typically want the client to bind to a dynamic source port so that multiple clients can co-exist on a single client system. The server can then respond to the client using the dynamic source port provided via the src port from request used as destination port in the response. Using a known port for peers allows you to configure UDP forwarding in NAT devices.
ex client/server with server on known port 3000
client binds to a random port (1234) but knows server is listening on port 3000.
client (src 1234) -> server (dst 3000)
server (dst 1234) -> client (src 3000)
...
If a computer has multiple interfaces you should expect to either need to explicitly bind a listener or sender to a specific IP address or be able to handle requests and responses from a peer being sent and recieved from a random IP based on the whims of the computers routing table. If you choose to bind requests to a specific interface then you need to be cognizant of the routing table if messages from a multi-homed system need to transit a different local interface for delivery. For example if you bind a UDP socket to 127.0.0.1 you obviously can't use it to send to any Internet routable IP Addresss.
In terms of protocol design its common to frame a session id and sequence fields in the UDP payload so that peers can keep track of sessions and individual exchanges.
There are a whole host of fragmentation, NAT coexistance, security and congestion issues you need to be aware of to successfully design a robust UDP protocol. I advise against it unless absolutely necessary.

Categories

Resources