Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some java Datagram Socket questions

I have recently nose dived into socket programming using java, and I have a few general sort of questions.

There is a bind() method, as well as a connect() and disconnect(). There is no unbind(). Is this because upon disconnecting the socket is unbound? Does garbage collection take care of this once the program exits? Or is this not even a valid question?

Also, upon creating a DatagramSocket, how is it different if I only provide the port and the address? I am creating a program to collect data off a network, as the data floats around and log it. Should I just use the local address? Could not using the address when I create the socket cause me to not be able to collect packets?

I am just trying to get a stronger understanding on the inner-workings of these things.

like image 985
Cat Avatar asked Jun 15 '11 17:06

Cat


People also ask

What protocol is used by the datagram socket class?

The DatagramSocket class implements packet-oriented, connectionless data communication. In Internet parlance, this is the User Datagram Protocol, commonly known as UDP (see RFC 768).

Why do we use datagram sockets?

A datagram socket is the sending or receiving point for a packet delivery service. Each packet sent or received on a datagram socket is individually addressed and routed. Multiple packets sent from one machine to another may be routed differently, and may arrive in any order.

What is difference between socket and DatagramSocket?

A ServerSocket is for accepting incoming network connections on some stream protocol; e.g. TCP/IP. A datagram is bunch of information sent in a single logical packet. For example, a UDP packet.

Which constructor socket is datagram?

DatagramSocket(): A datagram socket is constructed using the DatagramSocket() constructor, and it is bound to the available port on the local host machine. DatagramSocket(int): A datagram socket is constructed using the DatagramSocket() constructor, and it is bind to the specified port on the local host machine.


2 Answers

There are about 15 independent questions in there, but I'll do my best to address them:

There is a bind() method, as well as a connect() and disconnect(). There is no unbind(). Is this because upon disconnecting the socket is unbound?

bind() is separate from connect() and disconnect(). Bind is used to bind a socket to a particular port -- effectively to "listen" for connections whereas connect() is used to open a connection to a socket that is already listening on a particular port. The equivalent of unbind() is close()

Does garbage collection take care of this once the program exits? Or is this not even a valid question?

This is a totally valid question, although garbage collection is a technology used for memory management, not socket/OS resource management. If you don't release a particular port, it will remain associated with your application until your application terminates and it will then be reclaimed by the OS. This is OS-level functionality, not JVM functionality, etc.

Also, upon creating a DatagramSocket, how is it different if I only provide the port or provide the port and the address?

At some point, you have to provide the internet address and port or the socket you wish to connect to or to bind to. There's no way around it.

I am creating a program to collect data off a network, as the data floats around and log it. Should I just use the local address? Could not using the address when I create the socket cause me to not be able to collect packets?

I'm not sure what you're asking here, are you talking about logging all packets on the network, aka a sniffer? That's going to require more than simple datagram programming. You actually have to inject yourself at the network-adapter level to intercept packets as they are read off the line. What you're talking about will only allow you to receive packets that are sent to the specific port you're listening to.

like image 189
Chris Thompson Avatar answered Sep 21 '22 17:09

Chris Thompson


A DatagramSocket remains bound when disconnected, it is the close() method that would unbind it. Note that for a UDP (datagram) socket the semantics of connect() and disconnect() are different as compared to a TCP (or other connection oriented) socket. UDP is a connectionless protocol and a bound DatagramSocket can send and receive packets without being 'connected'. The connect() method has a purely local effect in that it causes the socket to only be able to send and receive packets to a given host/port, i.e. acting as a filter. A DatagramSocket connected to a multicast or broadcast address will only be able to send packets and not receive them.

bind(SocketAddress) is used to attach a socket to a local address/port combination, before a socket is bound it cannot receive or send any packets. The default behaviour of the constructors is to bind the socket immediately. To create an unbound 'DatagramSocket' use the DatagramSocket(SocketAddress) constructor passing null as an argument. Then it is possible to apply any custom configuration to the socket before binding it with bind().

As far as I know an open DatagramSocket that goes out of scope will cause a resource leak, the object may be garbage collected, but I'm pretty sure the underlying UDP socket will remain allocated by the OS until the JVM process exits.

If an address is not specified before the socket is bound, when bound it will attach to the wildcard address (INADDR_ANY), making it able to receive and send packets from any available local address (unless it is later 'connected' to some host). If a port is not specified (or specified as 0) then the socket is bound to some available port chosen by the OS (ephemeral port).

Edit: An example

// bind to INADDR_ANY, allowing packets on all IP addresses of host:
DatagramSocket dsock = new DatagramSocket(55555);
DatagramPacket packet = new DatagramPacket(new byte[8192]);

//next packet can be from anywhere including local host (127.0.0.0/8)
dsock.receive(packet);

// restrict communication to a single host/port:
dsock.connect(new InetSocketAddress("somehost.net", 99));

// next packet can only be from somehost.net on port 99:
dsock.receive(packet);
like image 37
willjcroz Avatar answered Sep 20 '22 17:09

willjcroz