c - bind() 套接字函数的第二个参数是什么?

标签 c sockets

我是 C 编程新手,目前正在学习 Unix 套接字编程。

我的问题是绑定(bind)函数的第二个参数实际上是什么?

int main(){
    int mysocket;
    int portno = 5004;

    mysocket = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serv_addr, cli_addr;
    struct sockaddr_in *p = &serv_addr;

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);


    bind(mysocket, p, sizeof(serv_addr));
}

我尝试传递 p*p,但不起作用。

最佳答案

bind()的第二个参数是一个指向结构体的指针,该结构体描述了套接字要绑定(bind)到的本地接口(interface)(第三个参数是该结构体的字节大小)。

bind() 采用 sockaddr* 指针作为输入,但它实际上接受任何与地址族匹配的 sockaddr_... 结构套接字(sockaddr_in 表示 AF_INETsockaddr_in6 表示 AF_INET6sockaddr_un 表示 AF_UNIX等)。

曾几何时,只有 sockaddr 存在(对于 AF_INET),以及 BSD 套接字 API(特别是 bind() accept()connect()get(sock|peer)name()) 是围绕 sockaddr 设计的。后来,当引入新的地址族时,创建了 sockaddr_in 作为之前 sockaddr 所表示的内容(IPv4 地址)的直接替代。但socket函数接口(interface)已经是一成不变的,无法更改。这就是为什么在调用此类函数时需要 sockaddr* 类型转换。所有 sockaddr_... 结构(包括 sockaddr 本身)都以 16 位 family 标识符开头,因此使用此类类型转换(协调与相关的字节大小参数)是安全的。

现在,在您的示例中,p 在第二个参数中传递,并且 p 声明为 Struct sockaddr_in *p = &serv_addr;,所以你实际上传入了 serv_addr 的内存地址(只有当参数声明为 void* 时,此代码才会编译,否则你将需要一个 sockaddr* 类型转换 - 这是平台相关的!)。 serv_addr 填充有 IPv4 地址(INADDR_ANY,又名 0.0.0.0)和端口号(portno,按网络字节顺序)。第三个参数设置为 sizeof(serv_addr)

因此,在该大小值和 serv_addr.sin_family 设置为 AF_INET 之间,bind() 知道您正在传递 sockaddr_in 结构,并将相应地验证和使用它。

关于c - bind() 套接字函数的第二个参数是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47821106/

相关文章:

c - 为什么这段代码能够访问空指针而不会导致崩溃?

c - C编程中如何检查输入是否等于预设值?

c - 如何使用外部库并将它们与 Contiki 应用程序一起编译

iphone - 在iPhone中监听TCP端口

c# - 字节序 java/.net

c - 我的 sqlite3 c 函数正在泄漏内存

c - 如何在 C 中定义一个接受格式化输入字符串的函数?

非阻塞套接字中的并发?

java - 在 Java 中通过套接字传递 JSON 对象数组

multithreading - 使用forkIO在Haskell "Concurrently, Asynchronously, Parallel, Non-Blocking"中进行Network.Socket编程