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.
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.
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);
来源:https://stackoverflow.com/questions/6361741/some-java-datagram-socket-questions