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

时间:2017-12-14 19:55:09

标签: c sockets

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

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

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,但它不起作用。

2 个答案:

答案 0 :(得分:2)

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

bind()sockaddr*指针作为输入,但它实际上接受与套接字的地址系列匹配的任何sockaddr_...结构(sockaddr_in AF_INETsockaddr_in6AF_INET6sockaddr_unAF_UNIX等。

曾几何时,只有sockaddr存在(对于AF_INET)和BSD套接字API(特别是bind()accept()connect()和{ {1}})围绕get(sock|peer)name()设计。稍后,当引入新地址系列时,sockaddr被创建为直接替换sockaddr_in之前表示的地址(IPv4地址)。但套接字功能接口已经完成,无法更改。这就是调用这些函数时需要sockaddr类型转换的原因。所有sockaddr*结构(包括sockaddr_...本身)都以16位sockaddr标识符开头,因此使用此类型类型转换(与关联的字节大小参数协调)是安全的。 / p>

现在,在您的示例中,family正在第二个参数中传递,p被声明为p,因此您实际上传递的内存地址为{{1} (此代码仅在参数声明为Struct sockaddr_in *p = &serv_addr;时才会编译,否则您需要serv_addr类型转换 - 这与平台有关!)。 void*填充了IPv4地址(sockaddr*,又名serv_addr)和端口号(INADDR_ANY,网络字节顺序)。第3个参数设置为0.0.0.0

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

答案 1 :(得分:0)

哎呀。从历史上看,起初只有struct sockaddr结构,后来发明了许多结构,例如:struc sockaddr_in,sockaddr_un结构。但是绑定函数已经设计了一个指针变量到第一个或开始结构sockaddr(历史上的第一个结构),现在我使用了sockaddr_in。  我看到成功绑定函数的唯一方法是:sockaddr * typecast:将类型的指针TYPECAST给另一个类型的指针。在我的例子是:类型转换指针p使用类型sockaddr_in到使用类型sockaddr的指针。如下所示:bind(mysocket,(struct sockaddr *)p,sizeof(serv_addr)),它可以工作。