在FreeBSD上,sctp_connectx()会返回EINVAL错误

14
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/sctp.h>
#include <stdio.h>
#include <string.h>

int main(int argc,char **argv)
{

    struct sockaddr_in remoteAddr;

    int clientSock = socket(PF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);
    if(clientSock == -1) {
        perror("socket");
        return 1;
    }
    memset(&remoteAddr,0,sizeof remoteAddr);
    remoteAddr.sin_family = AF_INET;
    remoteAddr.sin_len = sizeof remoteAddr;
    remoteAddr.sin_port = htons(5555);
    remoteAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    sctp_assoc_t assoc_id = 0;
    if(sctp_connectx(clientSock,(struct sockaddr*)&remoteAddr,1, &assoc_id)!= 0) {
        perror("sctp_connectx");
        return 1;
    }
    printf("Connected! Assoc ID %d\n",(int)assoc_id);

    return 0;   
}

当运行时,此代码失败:

$ clang  -Wall sctp_connect.c 
$ ./a.out 
sctp_connectx: Invalid argument
$ uname -rp
11.0-RELEASE-p9 amd64

但是我无法弄清楚哪里出了问题。 sctp_connectx() 手册中说,如果提供具有无效家族或无地址的地址,则会导致失败并返回 EINVAL - 但从代码上看似乎不是这种情况。

sctp_connectx() 有几个部分可能会因为 EINVAL 而失败,但 truss 显示它到达了 setsockopt() 调用,所以是内核失败了该调用:

socket(PF_INET,SOCK_SEQPACKET,132)       = 3 (0x3)
mmap(0x0,2097152,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 34374418432 (0x800e00000)
setsockopt(0x3,0x84,0x8007,0x800e16000,0x14)     ERR#22 'Invalid argument'

一个好的 [mcve]... 好的输出结果... 尝试独自解决这个问题... 为什么这个问题没有赞? - Stargateur
Linux上的那个人说:“EINVAL 无效的端口或地址。”希望这可以帮助到你。 - Stargateur
@amritanshu 如果使用SOCK_STREAM仍然存在同样的问题, - binary01
尝试找出你的地址是否有效?在将其转换为字符串ba2str()后打印地址。它似乎没有使用true参数。 https://www.freebsd.org/cgi/man.cgi?query=sctp_connectx&manpath=FreeBSD%208.0-RELEASE - EsmaeelE
http://petanode.com/blog/posts/sctp-specific-socket-functions-in-linux.html - EsmaeelE
显示剩余5条评论
1个回答

1

我认为你的问题已经在你的查询中得到了答案。如果我们按照 truss 的跟踪所述,它会在 setsockopt() 失败。

因此,EINVAL 错误是由 setsockopt() 返回的。根据 FreeBSD 的 setsockopt() 手册:

[EINVAL]: 尝试在非监听套接字上安装 accept_filter(9)。

这是错误的描述。所以我认为你应该做以下事情:

  1. 探索你的套接字选项是否正确与你的监听套接字相关。
  2. 检查函数 htons()inet_addr() 的错误。

我的建议是你不应该使用 inet_addr(),有关详细信息,请参阅 man 页面,如下所示:

使用此函数存在问题,因为 -1 是一个有效的地址 (255.255.255.255)。推荐使用 inet_aton()、inet_pton(3) 或 getaddrinfo(3),它们提供了一种更清晰的方法来指示错误返回。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接