我试图在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中报告“无效参数”。
发布于 2018-02-07 20:06:19
问题中有两个问题:
long作为参数,而Solaris则使用char。TL;DR:您应该在任何地方使用int。
在Solaris中,setsockopt()的定义可能略有不同,这取决于Solaris的版本和程序链接到的库,例如Solaris 10的setsockopt (3 3SOCKET)、setsockopt (3 3XNET)和Solaris 11的setsockopt (3 3SOCKET)、setsockopt (3 3XNET)。Linux手册共享与Solaris‘(3 3SOCKET)手册相同的内容:
大多数套接字级选项都使用optval的int参数。对于setsockopt(),参数应该是非零来启用布尔选项,或者如果要禁用该选项,则为零。
(3XNET)只是没有说明bolean选项的类型。然而,另一个UNIX (AIX)在单页上也有旧的*BSD和UNIX 98/XOPEN版本,其中它是布尔人的int。使用char的困惑来自(*BSD风格的)使用指向(char *)而不是(const void *)的指针转换的示例,因为原型使用的是*BSD/3XNET的char *。这并不意味着参数是char。至于long,除了不在定义之外,在int的体系结构上也是错误的。请注意,Windows与*NIX是不同的。
除了sizeof val应该是首选的事实,而且可以直接在setsockopt()中使用,而无需在这里使用len,len被定义为Solaris上的int (3XNET)和Solaris上的socklen_t (3 3SOCKET)和Linux,而不是任何地方的size_t。链接到可能的解释关于为什么int成为socklen_t的短文(而且是错误的)通过size_t。使用其他类型(如Linux上的size_t )在某些体系结构上可能会中断,而size_t没有被定义为int (参见前面的两个链接)。
https://stackoverflow.com/questions/48670299
复制相似问题