int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) { mss_now = tcp_send_mss(sk, &size_goal, flags); // code committed while (msg_data_left(msg)) { int copy = 0; int max = size_goal; skb = tcp_write_queue_tail(sk); if (tcp_send_head(sk)) { ... copy...
static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb) { __tcp_add_write_queue_tail(sk, skb); /* 把skb添加到发送队列的尾部 */ /* Queue it, remembering where we must start sending. */ if (sk->sk_send_head == NULL) { sk->sk_send_head = skb; /...
skb = tcp_write_queue_tail(sk); /* 如果接下来没有更多的数据需要发送,或者距离上次PUSH后又有比较多的数据, * 那么就需要设置PSH标志,让接收端马上把接收缓存中的数据提交给应用程序。 */ if (! (flags & MSG_MORE) || forced_push(tp)) tcp_mark_push(tp, skb); /* 如果设置了MSG_OOB标志,就...
skb=tcp_write_queue_tail(sk); 获取 TCP 写队列的尾部 有了这个skb之后,判断下要复制的数据长度。如果这个要复制的长度,没办法复制到当前的SKB中。那就得新建一个数据段。如果新建数据段,还得判断,是否有足够的流内存。还有可能会创建新的SKB,如果创建新的,还需要将SKB加入到 TCP写队列里面,通过 tcp_skb_en...
7. 调用tcp_write_queue_tail方法,从sk->sk_write_queue队列尾部拿出一个struct sk_buff实例,并赋值给skb变量。 8. 如果skb不为null,则看该skb还剩余多大的空间可写,把该值赋值给copy变量。 9. 如果skb为null,或者skb没有可写空间了,此时copy为0,则调用sk_stream_alloc_skb方法,创建一个新的struct sk_bu...
skb = tcp_write_queue_tail(sk); if (tcp_send_head(sk)) { //判断是否还有未发送的数据,即sk_send_head是否非空, if (skb->ip_summed == CHECKSUM_NONE) max = mss_now; copy = max - skb->len; } //不能够填充到sk_send_head指向的SKB的话,新建一个SKB ...
tcp_add_write_queue_tail(sk, skb); ///增加sk_wmem_queued. sk->sk_wmem_queued += skb->truesize; ///这里调整sk_forward_alloc的大小,也就是预分配buf的大小(减小). sk_mem_charge(sk, skb->truesize); if (tp->nonagle & TCP_NAGLE_PUSH) ...
skb=tcp_write_queue_tail(sk); if(tcp_send_head(sk)) { if(skb->ip_summed==CHECKSUM_NONE)//校验和的相关知识详见段三。 max=mss_now; /*本次循环copy的数据长度。max是当前SKB的最大数据长度,skb->len是当前skb的数据长度,相减得到当前skb的剩余数据空间。*/ ...
skb = tcp_write_queue_tail(sk); if (!skb) return; if (!(flags & MSG_MORE) || forced_push(tp)) tcp_mark_push(tp, skb); tcp_mark_urg(tp, flags); if (tcp_should_autocork(sk, skb, size_goal)) { avoid atomic op if TSQ_THROTTLED bit is already set ...
sk->saddr)sk->saddr=rt->rt_src;// 6. 如果没有指定源IP地址, 那么使用路由信息的源IP地址sk->rcv_saddr=sk->saddr;...// 7. 初始化TCP序列号tp->write_seq=secure_tcp_sequence_number(sk->saddr,sk->daddr,sk->sport,usin->sin_port);...// 8. 重置TCP最大报文段大小tp->mss_clamp=~...