bind函数用于给套接字命名。所谓命名指的是给一个协议地址赋予一个套接字。只有命名的套接字才能被其他进程找到。通常只有提供对外服务的套接字需要bind(),客户端无需bind()。
服务端程序在调用bind()命名地址之后执行两个步骤:listent()和accept()
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);
- sockfd是套接字描数字
- myddr是套接字地址结构指针,一般由sockddr_in或sockaddr_in6转型。
- addrlen是套接字地址结构的sizeof值
成功返回0,失败返回-1
bind操作涉及三个对象:套接字、地址和端口。其中套接字是捆绑的主体,地址和端口是捆绑的客体。bind可以指定IP地址或端口,可以都指指定,也可以都不指定。
IP地址 | 端口 | bind函数执行结果 |
---|---|---|
通配地址 | 0 | 内核选择IP地址和端口 |
通配地址 | 非0 | 内核选择IP地址,进程指定端口 |
本地IP地址 | 0 | 进程指定IP地址,内核选择端口 |
本地IP地址 | 非0 | 进程指定IP地址或端口 |
记忆的方法就是: |
- 对于IP地址,若为通配地址(INADDR_ANY)则由内核选择IP地址
- 端口为0,则由内核来选择端口。非0则由进程将该非0值设为端口
在头文件<netinet/in.h>
中,定义了一个宏INADDR_ANY称作通配名表示地址0.0.0.0,系统解释这个地址为程序运行所在机器的任意合法网络地址。
适用于单主机多IP的情况:假设主机有两个IP,用0来命名的套接字,那么进程可以接收这两个IP地址的连接。
尽管INADDR_ANY(值为0)的两种字节序是一样的,但因为<netinet/in.h>
中定义的所有**INADDR_**常值,它们都是主机字节序的,所以习惯上依旧要使用htonl函数进行转换。