linux协议栈TCP代码流程

Linux协议栈实现分析图_页面_3

Linux协议栈实现分析图_页面_3

Linux协议栈实现分析图_页面_3

tcp有两个sock结构hash

hashinfo->ehash

hashinfo->lhash

滑动窗口:发送窗口、接收窗口

Linux协议栈实现分析图_页面_3

发送窗口(swnd)

接受窗口(rwnd)

拥塞窗口(cwnd)

发送窗口=Min(拥塞窗口,接受窗口)

滑动窗口和拥塞窗口

https://blog.csdn.net/qq_41890651/article/details/120155783

高性能网络编程2—-TCP消息的发送

https://taohui.blog.csdn.net/article/details/9370109

高性能网络编程3—-TCP消息的接收

https://blog.csdn.net/russell_tao/article/details/9950615

计网 - TCP 的稳定性:滑动窗口和流速控制是怎么回事?

https://blog.51cto.com/u_15239532/3009395

TCP发送源码学习(2)–tcp_write_xmit

http://sunjiangang.blog.chinaunix.net/uid-9543173-id-3543419.html

1
2
3
4
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int socket(int domain, int type, int protocol);

domain用来选择通信协议,参数主要有一下一些常用类型

AF_UNIX, AF_LOCAL :用于本地通信,Unix Domain Socket
AF_INET :IPv4协议栈
AF_INET6 :IPv6协议栈

type参数定义通信语义

SOCK_STREAM:提供一种有序的,可靠的,双向的,基于连接的字节流
SOCK_DGRAM:支持数据报文(非连接的,不可靠的具有固定的最大字节长度的消息)
SOCK_SEQPACKET:提供一种有序的,可靠的,双向的基于连接的数据传输通道传输数据报文,报文的最大大小固定socket.SOCK_RAW
socket.SOCK_RDM

protocol参数指定和socket一起使用的特殊的协议栈(比如说SCTP),

SOCK_STREAM类型的socket是一个全双工的字节流,不预留消息边界:一个stream socket必须处于连接状态才能收发数据;通过调用connect()函数来连接到另一个创建的socket;一旦连接建立起来了,就可以通过read()和write()函数调用来进行数据传输了;最后调用close()函数关闭连接;实现了SOCK_STREAM的通信协议栈确保数据不会丢失或者重复;

SOCK_SEQPACKET使用的系统调用和SOCK_STREAM类型的socket一样,唯一的差异是read(2)函数只会返回请求的大小的数据包,多余的接收数据会被丢弃。同时会预留报文的消息边界

tcp发送流程

tcp_sendmsg->tcp_sendmsg_locked ->

tcp_push_one -> tp->ops->write_xmit-> tcp_write_xmit -> tcp_transmit_skb

tcp_push -> __tcp_push_pending_frames() -> tcp_write_xmit -> tcp_transmit_skb

tcp_sendmsg

该函数是将待发送的数据组织成一个个的skb,而且将这些skb按照前后顺序放入到发送队列sk_write_queue中。而且该函数也会尝试调用tcp_push()(以及其它两个接口)进行一次新数据发送。

tp->ops->write_xmit

该注册回调是mptcp为了实现subflow操作实现加入的

tcp_write_xmit

该函数是TCP发送新数据的核心函数,包括发送窗口判断、拥塞控制判断等核心操做都是在该函数中完成。

tcp_transmit_skb

该函数为传入的skb构造TCP首部,而后调用IP层的输出接口完成数据发送。

Linux协议栈实现分析图_页面_3

Linux协议栈实现分析图_页面_3

服务端

内核ip层收到报文到tcp

tcp_v4_rcv (报文校验)

|

V

tcp_v4_do_rcv

{

​ //当状态是ESTABLISHED时接收数据报文

​ if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */

​ {

​ tcp_rcv_established(sk, skb);

​ }

​ //当状态不是ESTABLISHED时 进行tcp协议例如3次握手

​ tcp_rcv_state_process(sk, skb)

|

tcp_ipv4.c

int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)

客户端

int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)

{

​ rt = ip_route_connect(); //查找路由

​ err = tcp_connect(sk); //发送syn 并创建定时器

}

内核收到报文复制到用户态

int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,int flags, int *addr_len)

TCP重传

tcp_init_sock -> tcp_init_xmit_timers 注册了tcp_retransmit_timer

tcp_retransmit_timer 定时

报文重传的次数

TCP报文重传的次数也根据系统设置的不同而有区分,有些系统,一个报文只会被重传3次,如果重传三次后还未收到该报文的确认,那么就不再尝试重传,直接reset重置该TCP连接,但有些要求很高的业务应用系统,则会不断的重传被丢弃的报文,以尽最大可能保证业务数据的正常交互。

TCP数据发送之发送新数

https://blog.csdn.net/fanxiaoyu321/article/details/85460896

Linux中TCP流程详解

https://blog.csdn.net/qq_40276626/article/details/120569084

linux tcp 优化案例详解

https://wenku.baidu.com/view/f587d2e90975f46527d3e11d.html


linux协议栈TCP代码流程
http://blog.uanet.cn/NETWORK/linux协议栈TCP代码流程.html
作者
dnsnat
发布于
2022年5月20日
许可协议