正如我们所知,我们使用类似的代码,并使用UDP套接字接收数据包:
DatagramSocket s = new DatagramSocket();
byte[] buf = new byte[1024];
DatagramPacket p = new DatagramPacket(buf, buf.length);
s.receive(p);
我想知道为什么函数receive()
而不是设置传递的数据包而不是返回数据包对象。
为什么这个API设计得像这样?这种设计方法有哪些优点,哪些有缺点?
答案 0 :(得分:2)
当您查看代码时,您会发现" user"定义缓冲区数组,稍后套接字将使用该数组实际存储数据。
因此,此API的用户对完整控件有关将要使用的内存/缓冲区。
当然,这也使它变得更复杂"使用该界面。但是当你处理这种低级别接口时,很可能你希望能够控制这些微妙的细节。
含义:当你进入"我自己的数据报协议实现"时,你真的知道你为什么这样做。然后"更多学位"自由是一件好事。
或者,JB Nizet的解释也是合理的:这个API基本上已经超过17年了。有可能是一个简单的副本"当时人们在使用C / C ++做了些什么。
来自那里:如果要创造一个"新鲜的"为此目的的API,它很可能看起来很不一样,更多"抽象"近来。
答案 1 :(得分:2)
我想知道为什么函数receive()而不是设置传递的数据包 而不是返回一个数据包对象。
将receive()
中的参数传递为DatagramSocket
允许的事项
设置一个缓冲区来保存传入的数据报,但整体指定要读取的字节数
它是通过DatagramPacket
参数完成的:
数据报包对象的长度字段包含长度 收到的消息。 如果邮件长于数据包 长度,邮件被截断。
正如您所注意到的,DatagramPacket
返回后还需要receive()
,其中包括DatagramPacket
的缓冲区中填充了客户端发送的数据。
可以使用特定于接收配置的输入中的不同参数来定义该方法,并且可以使用另一个特定于客户端发送的信息的输出来定义该方法。例如:
public synchronized DatagramPacketOutput receive(DatagramPacketInput p) throws IOException {
但API设计人员选择使用单个参数并将其用作输入输出参数
请注意,receive()
方法上的同步依赖于DatagramPacketInput
参数的锁定:
public synchronized void receive(DatagramPacket p) throws IOException {
synchronized (p) {
...
}
...
}
我认为返回void
是一种强调它的方法。