几个星期以来,我一直在为这个问题苦苦思索,终于接受了我无法弄清楚的事实。我也一直在与我的团队中的网络工程师合作,但无济于事。我的问题如下:
我正在开发一个应用程序,该应用程序在多个 vlan 上执行非常直接的 UDP 组加入(每个 vlan 都作为其自己的虚拟接口(interface)公开,在这种情况下,如果相关,NIC 是 SolarFlare)。所有这些连接都发生在单个套接字上(其中消息根据有效负载序列号进行重复数据删除)。在执行 IP_ADD_MEMBERSHIP 之前,我设置套接字选项如下:
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &yes, sizeof yes)
setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes))
setsockopt(sock, IPPROTO_IP, PACKET_AUXDATA, &yes, sizeof(yes))
我需要通过 IP_PKTINFO 获取接口(interface)索引或通过 PACKET_AUXDATA 获取 vlan id,以便在下游收集统计信息。现在,一切都在没有错误的情况下初始化,我能够毫无问题地处理 UDP 有效负载。我遇到麻烦的地方是当我尝试访问上面请求的辅助/控制消息时,如简单调试日志所示:
for (cmsgptr = CMSG_FIRSTHDR(&msg);
cmsgptr != NULL;
cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
printf("Control Message: cmsg_level: %d, cmsg_type %d\n", cmsgptr->cmsg_level, cmsgptr->cmsg_type);
}
对于收到的每个数据包,这只会输出:
Control Message: cmsg_level: 1, cmsg_type 29
作为引用,SOL_SOCKET=1 和 SO_TIMESTAMP=29。因此,尽管我请求 3 种不同的控制消息类型,但只填充了时间戳。此行为与我是加入单个接口(interface)上的单个 UDP 组还是多个接口(interface)上的多个组无关。
一种解决方案是重写应用程序,将每个接口(interface)放在自己的套接字上,然后将所有内容汇集到一个队列中,但根据我的经验,上下文切换会降低应用程序的性能。根据 ip(7) 手册页,IP_PKTINFO 自 Linux 内核 2.2 起可用。我正在运行使用内核 3.13.0-24-generic 的 Ubuntu 14.04.4。
如有任何帮助、见解或指导,我们将不胜感激!
最佳答案
暗中猜测
1) 在每次成功调用 setsockopt 后,您需要将 yes 重置回 1。文档暗示这不是必需的,但这是我会做的。
int yes = 1;
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &yes, sizeof(yes));
yes = 1;
setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes));
yes = 1;
setsockopt(sock, IPPROTO_IP, PACKET_AUXDATA, &yes, sizeof(yes));
2) 您是否正在检查 setsockopt 的返回值以查看这些调用是否正确成功。目前尚不清楚您是否已验证它们是否返回“0”表示成功或“-1”表示错误。您应该打印出每次调用的返回码。
3) 你没有显示你的 recvmsg 代码,你可能用它来获取额外信息。但是 struct msghdr 可能未正确初始化。具体来说,您的缓冲区是否足够大以获取所有控制数据?以下是我在代码中的做法:
struct iovec vec;
ssize_t ret;
const size_t CONTROL_DATA_SIZE = 1000; // THIS NEEDS TO BE BIG ENOUGH.
char controldata[CONTROL_DATA_SIZE];
struct msghdr hdr = {};
sockaddr_storage addrRemote = {};
vec.iov_base = buf;
vec.iov_len = len;
hdr.msg_name = &addrRemote;
hdr.msg_namelen = sizeof(addrRemote);
hdr.msg_iov = &vec;
hdr.msg_iovlen = 1;
hdr.msg_control = controldata;
hdr.msg_controllen = CONTROL_DATA_SIZE;
ret = ::recvmsg(sockfd, &hdr, flags);
关于c - IP_PKTINFO 套接字选项不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37597410/
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成
我目前正在尝试学习RubyonRails和测试框架RSpec。assigns在此RSpec测试中做什么?describe"GETindex"doit"assignsallmymodelas@mymodel"domymodel=Factory(:mymodel)get:indexassigns(:mymodels).shouldeq([mymodel])endend 最佳答案 assigns只是检查您在Controller中设置的实例变量的值。这里检查@mymodels。 关于ruby-o
一段时间以来,我一直在使用open_uri下拉ftp路径作为数据源,但突然发现我几乎连续不断地收到“530抱歉,允许的最大客户端数(95)已经连接。”我不确定我的代码是否有问题,或者是否是其他人在访问服务器,不幸的是,我无法真正确定谁有问题。本质上,我正在读取FTPURI:defself.read_uri(uri)beginuri=open(uri).readuri=="Error"?nil:urirescueOpenURI::HTTPErrornilendend我猜我需要在这里添加一些额外的错误处理代码...我想确保我采取一切预防措施来关闭所有连接,这样我的连接就不是问题所在,但是我
我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d