Socket之bind、listen实现

 我来答
舒适还明净的海鸥i
2022-06-09 · TA获得超过1.7万个赞
知道小有建树答主
回答量:380
采纳率:0%
帮助的人:68.1万
展开全部

bind()函数的使用方法很简单,但是它是怎么实现的呢?
本文将从应用层出发,沿着网络协议栈,分析了bind()、 listen()的系统调用、Socket层实现,以及它的TCP层实现。

应用层

int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);

bind() gives the socket sockfd the local address my_addr.

给socket描述符绑定IP和端口,一般服务器才需要。端口号的范围为0 ~ 65535。调用bind()时,一般不要把端口号置为小于1024的值,因为1到1023是保留端口号。

系统调用

bind()是由glibc提供的,声明位于include/sys/socket.h中,实现位于sysdeps/mach/hurd/bind.c中,主要是用来从用户空间进入名为sys_socketcall的系统调用,并传递参数。sys_scoketcall()实际上是所有socket函数进入内核空间的共同入口。
在sys_socketcall()中会调用sys_bind()。

经过了socket层的总入口sys_socketcall(),现在进入sys_bind()。

经过了socket层的总入口sys_socketcall(),现在进入sys_bind()。

通过文件描述符,找到对应的file结构。

通过file结构,找到对应的socket结构。

把用户空间的socket地址复制到内核空间,同时检查是否合法,成功返回0。

socket层

SOCK_STREAM套接口的socket层操作函数集实例为inet_stream_ops,其中绑定函数为inet_bind()。

socket层做的主要事情为合法性检查、绑定IP地址,而真正的端口绑定是在TCP层进行的。

应用层
int listen(int sockfd, int backlog);
Accept incoming connections and a queue limit for incoming connections.

backlog的定义

Now it specifies the queue length for completely established sockets waiting to be accepted,

instead of the number of incomplete connection requests. The maximum length of the queue

for incomplete sockets can be set using the tcp_max_syn_backlog sysctl. When syncookies

are enabled there is no logical maximum length and this sysctl setting is ignored.

全连接队列的最大长度:
backlog保存的是完成三次握手、等待accept的全连接,而不是半连接。
负载不高时,backlog不用太大。(For complete connections)

系统最大的、未处理的全连接数量为:min(backlog, somaxconn),net.core.somaxconn默认为128。

半连接队列的最大长度:
tcp_max_syn_backlog默认值为256。(For incomplete connections)
当使用SYN Cookie时,这个参数变为无效。

半连接队列的最大长度为backlog、somaxconn、tcp_max_syn_backlog的最小值。

listen()是由glibc提供的,声明位于include/sys/socket.h中,实现位于sysdeps/mach/hurd/listen.c中,主要是用来从用户空间进入名为sys_socketcall的系统调用,并传递参数。sys_socketcall()实际上是所有socket函数进入内核空间的共同入口。
在sys_socketcall()中会调用sys_listen()。

经过了socket层的总入口sys_socketcall(),现在进入sys_listen()。

SOCK_STREAM套接口的socket层操作函数集实例为inet_stream_ops,其中监听函数为inet_listen()。

检查套接口的状态、当前连接的状态是否合法,然后调用inet_csk_listen_start()启动监听。

启动监听时,做的工作主要包括:

listen_sock结构用于保存SYN_RECV状态的连接请求块,所以也叫半连接队列。

(1)创建

queue是连接请求控制块,nr_table_entries是半连接的最大个数,即backlog。

(2)销毁
销毁连接请求块中的listen_sock实例,释放半连接队列。

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式