我正在尝试在我的ftp程序中在Linux和Solaris上使用setsockopt()
。
Linux使用long
作为optvalue
作为参数,但Solaris使用char
代替。
#ifdef sun
char val;
#else
long val;
#endif
#ifdef sun
val = 1;
size_t len = sizeof(char);
if(setsockopt(s_socket_fd, SOL_SOCKET, SO_REUSEADDR, &val, len) == -1) {
perror("Fail");
exit(1);
}
#else
val = 1;
size_t len = sizeof(long);
if(setsockopt(s_socket_fd, SOL_SOCKET, SO_REUSEADDR, &val, len) == -1) {
perror("Fail");
exit(1);
}
#endif
该程序在Linux中运行良好,但在创建套接字时在Solaris中报告“无效参数”。
答案 0 :(得分:3)
问题中出现了两个问题:
Linux使用
long
作为参数的optvalue,但Solaris使用char
代替。
TL; DR:你应该到处使用int
。
在Solaris中,setsockopt()
的定义可能略有不同,具体取决于Solaris的版本和程序链接的库,例如Solaris 10 setsockopt (3SOCKET),{{3}和Solaris 11' setsockopt (3XNET),setsockopt (3SOCKET)。 setsockopt (3XNET)与Solaris'}共享相同的内容。 (3SOCKET)联机帮助页:
大多数套接字级选项都使用 int 参数进行optval。对于 setsockopt(),参数应该非零以启用布尔值 选项,如果要禁用该选项,则为零。
(3XNET)只是没有说明bolean选项的类型。然而,另一个UNIX(AIX)在Linux' manpage上也有旧的* BSD和UNIX98 / XOPEN版本,它们对于布尔值来说是int
。关于使用char
的混淆来自(* BSD样式)示例,使用指针转换为(char *)
而不是(const void *)
,因为原型使用char *
来表示* BSD / 3XNET。这并不意味着参数为char
。至于long
,除了不在定义之外,还有single page那些错误的架构。请注意,Windows与* NIX不同。
size_t len = sizeof(char);
除了sizeof val
应该首选,并且可以直接在setsockopt()
中使用,而不需要首先使用len
,len
是在Solaris(3XNET)上定义为int
,在Solaris(3SOCKET)和Linux上定义为socklen_t
,而在任何地方定义为size_t
。 int
socklen_t
为什么size_t
通过size_t
短暂(和错误)通过size_t
。当int
未定义为protected void requestBoth() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CAMERA}, MULT_KEY);
}
protected void requestLoc() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCPERMISSION_KEY);
}
protected void requestCam() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMPERMISSION_KEY);
}
public void request() {
if ((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)) {
requestUpdates();
} else if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
requestCam();
} else if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
requestLoc();
} else {
requestBoth();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= 23) {
request();
}
}
时,使用其他类型(例如Linux上的re.sub
)可能会破坏某些体系结构(请参阅前面的2个链接)。