linux协议栈TCP代码流程
tcp有两个sock结构hash
hashinfo->ehash
hashinfo->lhash
滑动窗口:发送窗口、接收窗口
发送窗口(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 |
|
domain用来选择通信协议,参数主要有一下一些常用类型
AF_INET
AF_UNIX
AF_NS
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发送流程
send
================kernel==============
__sys_sendto
sock_sendmsg -> sock->ops->sendmsg
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层的输出接口完成数据发送。
服务端
内核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 优化案例详解