java 一些java数据报套接字问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6361741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Some java Datagram Socket questions
提问by Cat
I have recently nose dived into socket programming using java, and I have a few general sort of questions.
我最近一头扎进了使用 java 的套接字编程中,我有一些一般性的问题。
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?
有一个 bind() 方法,以及一个 connect() 和 disconnect()。没有解除绑定()。这是因为断开连接时套接字未绑定吗?一旦程序退出,垃圾收集会处理这个问题吗?或者这甚至不是一个有效的问题?
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?
另外,在创建 DatagramSocket 时,如果我只提供端口和地址有什么不同?我正在创建一个程序来从网络收集数据,因为数据会四处浮动并记录下来。我应该只使用本地地址吗?创建套接字时无法使用地址导致我无法收集数据包?
I am just trying to get a stronger understanding on the inner-workings of these things.
我只是想对这些事物的内部运作有更深入的了解。
回答by Chris Thompson
There are about 15 independent questions in there, but I'll do my best to address them:
那里大约有 15 个独立的问题,但我会尽力解决它们:
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() 方法,以及一个 connect() 和 disconnect()。没有解除绑定()。这是因为断开连接时套接字未绑定吗?
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()
bind()
与connect()
和分开disconnect()
。绑定用于将套接字绑定到特定端口——有效地“侦听”连接,而connect()
用于打开到已经在特定端口上侦听的套接字的连接。相当于unbind()
ISclose()
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.
这是一个完全有效的问题,尽管垃圾收集是一种用于内存管理的技术,而不是套接字/操作系统资源管理。如果您不释放特定端口,它将与您的应用程序保持关联,直到您的应用程序终止,然后由操作系统回收。这是操作系统级别的功能,而不是 JVM 功能等。
Also, upon creating a DatagramSocket, how is it different if I only provide the port or provide the port and the address?
另外,在创建 DatagramSocket 时,如果我只提供端口或提供端口和地址有什么不同?
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.
在某些时候,您必须提供 Internet 地址和端口或您希望连接或绑定的套接字。没有办法解决它。
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.
我不确定你在这里问的是什么,你说的是记录网络上的所有数据包,也就是嗅探器?这将需要的不仅仅是简单的数据报编程。您实际上必须在网络适配器级别注入自己以拦截从线路读取的数据包。您所谈论的内容仅允许您接收发送到您正在侦听的特定端口的数据包。
回答by willjcroz
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.
ADatagramSocket
断开连接时保持绑定,它是close()
解除绑定的方法。请注意,对于 UDP(数据报)套接字,connect()
与disconnect()
TCP(或其他面向连接的)套接字相比,其语义和是不同的。UDP 是一种无连接协议,绑定DatagramSocket
可以在没有“连接”的情况下发送和接收数据包。该connect()
方法具有纯粹的本地效果,因为它使套接字只能向给定的主机/端口发送和接收数据包,即充当过滤器。一个DatagramSocket
连接到多播或广播地址只能发送数据包,而不是接受他们。
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()
.
bind(SocketAddress)
用于将套接字附加到本地地址/端口组合,在绑定套接字之前它不能接收或发送任何数据包。构造函数的默认行为是立即绑定套接字。要创建未绑定的“DatagramSocket”,请使用作为参数DatagramSocket(SocketAddress)
传递的构造null
函数。然后可以在将其与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.
据我所知DatagramSocket
,超出范围的打开会导致资源泄漏,对象可能会被垃圾收集,但我很确定底层 UDP 套接字将保持由操作系统分配,直到 JVM 进程退出。
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).
如果在绑定套接字之前未指定地址,则绑定时它将附加到通配符地址 ( INADDR_ANY
),使其能够从任何可用的本地地址接收和发送数据包(除非它稍后“连接”到某个主机)。如果未指定端口(或指定为 0),则套接字将绑定到操作系统选择的某个可用端口(临时端口)。
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);