一些java Datagram Socket问题

我最近已经厌倦了使用java进行套接字编程,我有几个一般的问题。

有一个bind()方法,以及一个connect()和disconnect()。 没有unbind()。 这是因为在断开套接字时是未绑定的吗? 一旦程序退出,垃圾收集是否会处理这个问题? 或者这甚至不是一个有效的问题?

另外,在创建DatagramSocket时,如果我只提供端口和地址,它有何不同? 我正在创建一个程序来从网络上收集数据,因为数据会浮动并记录下来。 我应该只使用本地地址吗? 我创建套接字时无法使用该地址导致我无法收集数据包?

我只是想更深入地了解这些事情的内部运作。

那里有大约15个独立的问题,但我会尽力解决它们:

有一个bind()方法,以及一个connect()和disconnect()。 没有unbind()。 这是因为在断开套接字时是未绑定的吗?

bind()connect()disconnect()分开。 Bind用于将套接字绑定到特定端口 – 有效地“侦听”连接,而connect()用于打开已经侦听特定端口的套接字的连接。 unbind()的等价物是close()

一旦程序退出,垃圾收集是否会处理这个问题? 或者这甚至不是一个有效的问题?

这是一个完全有效的问题,尽管垃圾收集是一种用于内存管理的技术,而不是套接字/ OS资源管理。 如果您没有释放特定端口,它将与您的应用程序保持关联,直到您的应用程序终止,然后由操作系统回收它。 这是操作系统级function,而不是JVMfunction等。

另外,在创建DatagramSocket时,如果我只提供端口或提供端口和地址,它有何不同?

在某些时候,您必须提供您希望连接或绑定到的Internet地址和端口或套接字。 没有办法绕过它。

我正在创建一个程序来从网络上收集数据,因为数据会浮动并记录下来。 我应该只使用本地地址吗? 我创建套接字时无法使用该地址导致我无法收集数据包?

我不确定你在这里问的是什么,你是在谈论在网络上记录所有数据包,又叫嗅探器? 这将需要的不仅仅是简单的数据报编程。 实际上,您必须在网络适配器级别注入自己,以便在数据包读取时拦截数据包。 您所谈论的内容只允许您接收发送到您正在侦听的特定端口的数据包。

断开连接时DatagramSocket保持绑定,它是解除绑定的close()方法。 请注意,对于UDP(数据报)套接字,与TCP(或其他面向连接的)套接字相比, connect()disconnect()的语义不同。 UDP是一种无连接协议,绑定的DatagramSocket可以在不“连接”的情况下发送和接收数据包。 connect()方法具有纯粹的局部效果,因为它使套接字只能发送和接收给定主机/端口的数据包,即充当filter。 连接到多播或广播地址的DatagramSocket只能发送数据包而不能接收数据包。

bind(SocketAddress)用于将套接字连接到本地地址/端口组合,在套接字绑定之前它不能接收或发送任何数据包。 构造函数的默认行为是立即绑定套接字。 要创建未绑定的“DatagramSocket”,请使用DatagramSocket(SocketAddress)构造函数将null作为参数传递。 然后,可以在将任何自定义配置与bind()之前将其应用于套接字。

据我所知,超出范围的开放DatagramSocket将导致资源泄漏,该对象可能被垃圾收集,但我很确定底层UDP套接字将保持由操作系统分配,直到JVM进程退出。

如果在绑定套接字之前未指定地址,则绑定时它将附加到通配符地址( INADDR_ANY ),使其能够从任何可用的本地地址接收和发送数据包(除非它稍后“连接”到某个主机) 。 如果未指定端口(或指定为0),则套接字将绑定到OS( 临时端口 )选择的某个可用端口。

编辑:一个例子

 // 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);