- 英文小册原文地址:beej.us/guide/bgnet…
- 作者:Beej
- 中文翻译地址:www.chanmufeng.com/posts/netwo…
将socket与IP地址和端口号关联。
函数原型
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
说明
当远程计算机想要连接到你的服务器程序时,它需要两条信息:IP地址和端口号。bind()
调用就是帮你做这件事情。
端口号是内核用来确认将收到的数据包交给哪个具体进程的socket descriptor
的依据。
通常在写服务端程序的时候我们才需要进行关联,客户端程序不需要我们手动绑定端口,直接
connect()
就好了。
首先,调用getaddrinfo()
加载一个包含目标地址和端口信息的结构sockaddr
,然后调用socket()
得到socket descriptor
,然后将socket
和地址传递到bind()
中,IP地址和端口就会神奇地被绑定到socket上!
如果你不知道你的IP地址,或者你知道你的机器上只有一个IP地址,或者你不在乎使用机器的哪一个IP地址的话,你可以简单地将提示参数中的AI_PASSIVE
标识传递给getaddrinfo()
。这其实是用一个特殊值填充struct sockaddr
的IP地址部分,该值告诉bind()
它应该自动填充该主机的IP地址。
什么什么?你想知道在struct sockaddr
的IP地址中加载了什么特殊值,使其自动用当前主机的IP填充地址?我会告诉你,但请记住,这只有在你手动填写struct sockaddr
的时候才会这样;否则乖乖照我上边说的,使用getaddrinfo()
的返回结果。
在IPv4中,struct sockaddr_in
结构的 sin_addr.s_addr
字段被设置成了INADDR_ANY
。在IPv6中,struct sockaddr_in6
结构的sin6_addr
字段被赋值成全局变量in6addr_any
。或者,如果你声明了一个新的 struct in6_addr
,你可以将其初始化为IN6ADDR_ANY_INIT
。
最后,addrlen
参数应该设置为 sizeof my_addr
。
返回值
成功返回0
,发生异常时返回-1
,并将 errno
设置为合适的值。
例子
// modern way of doing things with getaddrinfo()
struct addrinfo hints, *res;
int sockfd;
// first, load up address structs with getaddrinfo():
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
getaddrinfo(NULL, "3490", &hints, &res);
// make a socket:
// (you should actually walk the "res" linked list and error-check!)
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
// bind it to the port we passed in to getaddrinfo():
bind(sockfd, res->ai_addr, res->ai_addrlen);
// example of packing a struct by hand, IPv4
struct sockaddr_in myaddr;
int s;
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(3490);
// you can specify an IP address:
inet_pton(AF_INET, "63.161.169.137", &(myaddr.sin_addr));
// or you can let it automatically select one:
myaddr.sin_addr.s_addr = INADDR_ANY;
s = socket(PF_INET, SOCK_STREAM, 0);
bind(s, (struct sockaddr*)&myaddr, sizeof myaddr);
参阅
getaddrinfo(), socket(), struct sockaddr_in, struct in_addr
标签:sockaddr,addr,ai,bind,手册,socket,IP地址,man,struct From: https://blog.51cto.com/u_13887950/5806585