我遇到了问题 - 我不知道发送到UDP服务器的数据量。
目前的代码就是这样 - 用irb进行测试:
require 'sockets'
sock = UDPSocket.new
sock.bind('0.0.0.0',41588)
sock.read # Returns nothing
sock.recvfrom(1024) # Requires length of data to be read - I don't know this
我可以将recvfrom设置为65535或其他一些大数字,但这似乎是一个不必要的黑客。
recvfrom和recvfrom_nonblock都会在指定的长度之后扔掉任何东西。
我是否错误地设置了套接字?
答案 0 :(得分:4)
请注意,UDP是数据报协议,而不是像TCP一样的流。 UDP套接字的每次读取都会使一个完整的数据报出列。您可以将这些标记传递给recvfrom(2)
:
MSG_PEEK This flag causes the receive operation to return data from the beginning of the receive queue without removing that data from the queue. Thus, a subsequent receive call will return the same data. MSG_WAITALL This flag requests that the operation block until the full request is satisfied. However, the call may still return less data than requested if a signal is caught, an error or disconnect occurs, or the next data to be received is of a different type than that returned. MSG_TRUNC Return the real length of the packet, even when it was longer than the passed buffer. Only valid for packet sockets.
如果你真的不知道你可能得到多大的数据包(协议限制为65507
字节,请参阅here)并且不关心系统调用次数加倍,首先是MSG_PEEK
,然后从套接字中读取确切的字节数。
或者您可以设置近似的最大缓冲区大小,例如4096
,然后使用MSG_TRUNC
检查是否丢失了任何数据。
另请注意,UDP数据报很少大于1472
- 以太网数据大小1500
减去20
字节的IPv4标头减去8
字节的UDP标头 - 没人喜欢碎片。
Socket::MSG_PEEK
在那里,对于其他人,您可以使用整数值:
MSG_TRUNC 0x20
MSG_WAITALL 0x100
查看系统标题(Linux上的/usr/include/bits/socket.h
)以确定。
答案 1 :(得分:2)
查看Ruby的recvfrom()的文档,该参数是最大长度。只需提供65535(UDP数据报的最大长度);返回的数据应该是它发生的任何大小的发送数据报,你应该能够像Ruby中任何类似字符串的东西那样确定它的大小。