我正在尝试运行一个简单的C程序,该程序使用bind()函数将IPv4/IPv6地址绑定到套接字。
下面是代码:
第一个
当这个程序在Linux上编译和运行时,它可以正常工作,没有任何错误。但是当同一个程序在MacOS上编译和运行时,bind()函数返回一个“无效参数”错误。
我查看了bind()函数的手册页,了解了导致此错误的可能原因。三个可能的原因是:
1.套接字已绑定到另一地址
1.传递给函数的addrlen
值不正确
addr
不是此套接字域的有效地址
我能够证实这不是由于第一和第三个原因。
我的问题是,为什么传递给bind()函数的addrlen
值在Unix系统上运行时会抛出“参数不正确”错误,而在Linux系统上运行时却能正常工作?
1条答案
按热度按时间u4vypkhs1#
您传递给
bind()
的addrlen
值必须与您在socket()
中指定的地址族完全匹配。这意味着addrlen
必须设置为sizeof(sockaddr_in)
(对于AF_INET
)和sizeof(sockaddr_in6)
(对于AF_INET6
)。使用sizeof(sockaddr_storage)
是错误的值,由于X1M9N1X被设计为足够大以容纳所有可能的X1M10N1X类型,因此其大小可以大于X1M11N1X。另一方面,在调用
accept()
时,需要事先将addrlen
设置为addr
的完整大小,这样它就知道在将客户端地址写入addr
时需要使用多少内存。addrlen
将被调整为写入的实际大小。但是,您不能简单地将int*
类型转换为socklen_t*
,因此addrlen
需要是实际的socklen_t
类型。此外,bind()
需要的是socklen_t
,而不是int
。请尝试以下内容:
也就是说,应该使用
getaddrinfo()
来初始化传递给bind()
的sockaddr_...
,而不应该手动初始化它。