我有一个基于 TCP 的程序,它同时支持 IPv4 和 IPv6。所以我在代码中使用了“sockaddr_storage”。
在客户端端,我需要将客户端 TCP 端口固定到特定端口,因此我需要将套接字绑定(bind)到该地址。
struct sockaddr_storage local_addrs; //for local address
if (sc->domain == AF_INET) {
(*(struct sockaddr_in*)&local_addrs).sin_family = AF_INET;
(*(struct sockaddr_in*)&local_addrs).sin_addr.s_addr = inet_addr(INADDR_ANY);
(*(struct sockaddr_in*)&local_addrs).sin_port = htons(tcp_port);
}
else{
(*(struct sockaddr_in6*)&local_addrs).sin6_family = AF_INET6;
(*(struct sockaddr_in6*)&local_addrs).sin_addr.s_addr = inet_addr(IN6ADDR_ANY_INIT);
(*(struct sockaddr_in6*)&local_addrs).sin6_port = htons(tcp_port);
}
local_addr_size = sizeof(local_addrs);
if (( ret = bind(sockfd, (struct sockaddr *)&local_addrs, local_addr_size)) < 0 ) {
....//error
}
如何初始化struct sockaddr_storage local_addrs?我是否需要为此结构分配内存?
顺便说一句,下面的行还不能用。仍在尝试找出如何将客户端 sokcet 绑定(bind)到任何可能的 IPv6 地址。
(*(struct sockaddr_in6*)&local_addrs).sin_addr.s_addr = inet_addr(IN6ADDR_ANY_INIT);
最佳答案
您显示的代码基本上是正确的方法,因为您需要将 sockaddr_storage 类型转换为特定的 sockaddr_... 类型想要填充。
但是,在 sockaddr_in6 的情况下,IN6ADDR_ANY_INIT 部分是错误的。改用这个:
(*(struct sockaddr_in6*)&local_addrs).sin6_addr = in6addr_any;
IN6ADDR_ANY_INIT 是一个宏,只能在编译时用于静态声明,例如:
struct sockaddr_in6 in6 = {AF_INET6, port, 0, IN6ADDR_ANY_INIT, 0};
struct in6_addr addr = IN6ADDR_ANY_INIT;
IN6ADDR_ANY_INIT 不能在运行时用于赋值,例如:
struct sockaddr_in6 in6;
in6.sin6_addr = IN6ADDR_ANY_INIT; // ERROR
struct in6_addr addr;
addr = IN6ADDR_ANY_INIT; // ERROR
另一方面,in6addr_any 是一个全局变量,可在运行时用于赋值。
不,您不需要malloc sockaddr_storage 结构。
话虽如此,我建议使用一些局部变量来使代码更易于阅读:
if (sc->domain == AF_INET) {
struct sockaddr_in *in4 = (struct sockaddr_in*) &local_addrs;
in4->sin_family = AF_INET;
in4->sin_addr.s_addr = INADDR_ANY; // <-- inet_addr() is not needed for INADDR_ANY
in4->sin_port = htons(tcp_port);
}
else {
struct sockaddr_in6 *in6 = (struct sockaddr_in6*) &local_addrs;
in6->sin6_family = AF_INET6;
in6->sin6_addr = in6addr_any;
in6->sin6_port = htons(tcp_port);
/* note: sockaddr_in6 also has sin6_flowinfo and sin6_scope_id
fields that you may have to fill, too...
in6->sin6_flowinfo = ...;
in6->sin6_scope_id = ...;
*/
}
或者,使用union代替:
union sockaddr_types {
struct sockaddr_storage storage;
struct sockaddr addr;
struct sockaddr_in in4;
struct sockaddr_in6 in6;
};
union sockaddr_types local_addrs;
if (sc->domain == AF_INET) {
local_addrs.in4.sin_family = AF_INET;
local_addrs.in4.sin_addr.s_addr = INADDR_ANY;
local_addrs.in4.sin_port = htons(tcp_port);
}
else {
local_addrs.in6.sin6_family = AF_INET6;
local_addrs.in6.sin6_addr = in6addr_any;
local_addrs.in6.sin6_port = htons(tcp_port);
/*
local_addrs.in6.sin6_flowinfo = ...;
local_addrs.in6.sin6_scope_id = ...;
*/
}
if ((ret = bind(sockfd, &local_addrs.addr, sizeof(local_addrs))) < 0) {
//error...
}
无论哪种方式,您还应该考虑将整个 sockaddr_storage 归零以预填充未使用的字段,然后再填充您需要的内容:
memset(&local_addrs, 0, sizeof(local_addrs));
关于c - Linux: sockaddr_storage 怎么初始化呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50707444/
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R
我在我的Rails3示例应用程序上使用CarrierWave。我想验证远程位置上传,因此当用户提交无效URL(空白或非图像)时,我不会收到标准错误异常:CarrierWave::DownloadErrorinImageController#createtryingtodownloadafilewhichisnotservedoverHTTP这是我的模型:classPaintingtrue,:length=>{:minimum=>5,:maximum=>100}validates:image,:presence=>trueend这是我的Controller:classPaintingsC
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认
我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于