快捷搜索: 王者荣耀 脱发

socket缓冲区/sk_buffer/滑动窗口关系

之前看极客时间对内核缓冲区,socket缓冲区.sk_buffer,着实有些乱,整理了一下午,把这些概念理清,真是顺畅,通透啊!

首先,还是感谢极客时间大佬.关于网络协议方面的讲解,还有一些优秀博客(, )

1.socket.read和socket.write意味着什么

我们socket.write的时候,是把用户缓冲区内容拷贝到了内核缓冲区.写成功的话,是因为写缓冲区有空间可以写.(哈哈,这里就是滑动窗口机制).读成功,也是因为有数据可读.

2.socket缓存区

在创建套接字的时候,就会创建两个缓冲区,读缓冲区/写缓冲区(图中浅红色).这两个缓冲区互不影响.

1.当你在程序里 byte[] sb=new byte[]; 此时是在用户内存中创建了一小块内存.就是橘黄色部分里.

2.当你调用 socket.send(sb); 这时候是把这个用户内存数据拷贝到内核缓冲区.

tcp协议栈处理线程 会把数据封装成 sk_buffer 这个是底层数据接口,他是一个双链表.每一个sk_buffer都是一个帧.封装的过程就是不断添加协议头的过程.

3.内核缓冲区发送到对端.是内核协议栈做的事情.其中包括滑动窗口/拥塞控制.

滑动窗口其实就是对socket缓存的一些逻辑.具体就是对sk_buffer的逻辑.sk_buffer逻辑看sk_buffer.note

4.数据到达对端主机的输入缓冲区.这个过程不受用户程序控制,也是内核协议栈做的.包括返回ack

5.把内核缓冲区数据复制到用户内存.就是用户调用read操作.当复制到用户内存后,就说明这段数据可以删除了.窗口可以移动啦

那么我们再来思考下这个问题.如果接收端的程序里一直sleep,会怎么样

1.那么第五步不执行,就会导致数据一致积累在内核缓冲区(接收缓冲区).那么滑动窗口里.可以接受的大小就会变为0.那么就会告诉client.不要发送了我这没有空间接收了.md

2.那么client就不会发送了.client内核就会被塞满.因为client用户一直在write(把用户内存的数据拷贝到内核缓冲区(发送缓冲区)).等塞满了.那write就会出问题.因为你复制不过去了.

那么对用户来说,write不了,会怎么样呢?会阻塞吗?这个就要看用户write类型了.

经验分享 程序员 微信小程序 职场和发展