Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux:sockaddr\u存储如何初始化它?_C_Linux_Sockets_Tcp - Fatal编程技术网

Linux:sockaddr\u存储如何初始化它?

Linux:sockaddr\u存储如何初始化它?,c,linux,sockets,tcp,C,Linux,Sockets,Tcp,我有一个基于TCP的程序,它支持IPv4和IPv6。所以我在代码中使用了“sockaddr\u storage” 在客户端端,我需要将客户端TCP端口固定到特定端口,因此我需要将套接字绑定到该地址 struct sockaddr_storage local_addrs; //for local address if (sc->domain == AF_INET) { (*(struct sockaddr_in*)&local_addrs).sin_family = AF_

我有一个基于TCP的程序,它支持
IPv4
IPv6
。所以我在代码中使用了“
sockaddr\u storage

客户端端,我需要将客户端TCP端口固定到特定端口,因此我需要将套接字绑定到该地址

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
}

您显示的代码基本上是正确的,因为您需要将
sockaddr\u存储
类型强制转换为要填充的特定
sockaddr\u…
类型

但是,在
sockaddr\u in6
的情况下,
IN6ADDR\u ANY\u INIT
部分是错误的。改用这个:

(*(struct sockaddr_in6*)&local_addrs).sin6_addr = in6addr_any;
IN6ADDR\u ANY\u INIT
是一个宏,只能在编译时在静态声明中使用,例如:

struct sockaddr_in6 in6 = {AF_INET6, port, 0, IN6ADDR_ANY_INIT, 0};

IN6ADDR\u ANY\u INIT
不能在运行时的分配中使用,例如:

struct sockaddr_in6 in6;
in6.sin6_addr = IN6ADDR_ANY_INIT; // ERROR

另一方面,in6addr\U any是一个全局变量,可以在运行时用于分配

不,您不需要
malloc
存储
sockaddr\u
结构

也就是说,我建议使用一些局部变量使代码更易于阅读:

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 = ...;
    */
}

任一种方式,您也应该考虑将整个<代码> SokAdDrySturt< /C> >预先填充未使用的字段,然后填充所需的字段:

memset(&local_addrs, 0, sizeof(local_addrs));

为什么要绑定客户端套接字呢?这对于TCP来说是非常不寻常的。正如我在问题中所说的,我想将本地TCP端口绑定到一个特定的端口,以便进行测试。:)什么是
sc->domain
struct in6_addr addr;
addr = IN6ADDR_ANY_INIT; // ERROR
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 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...
}
memset(&local_addrs, 0, sizeof(local_addrs));