void tcp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, unsigned int len){ /* * Standard slow path. */ if (!tcp_validate_incoming(sk, skb, th, 1)) return;step5: if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) goto discard; tcp_rcv_rtt_measure_ts(sk, skb); /* Process urgent data. */ tcp_urg(sk, skb, th); /* step 7: process the segment text */ tcp_data_queue(sk, skb); tcp_data_snd_check(sk); tcp_ack_snd_check(sk); return;}/* This routine deals with incoming acks, but not outgoing ones. */static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag){ /* See if we can take anything off of the retransmit queue. */ acked = tp->packets_out; flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, sack_rtt); acked -= tp->packets_out;}/* Remove acknowledged frames from the retransmission queue. If our packet * is before the ack sequence we can discard it as it's confirmed to have * arrived at the other end. */static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, u32 prior_snd_una, s32 sack_rtt){ while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) { struct tcp_skb_cb *scb = TCP_SKB_CB(skb); if (after(scb->end_seq, tp->snd_una)) { fully_acked = false; } if (!fully_acked) break; tcp_unlink_write_queue(skb, sk); sk_wmem_free_skb(sk, skb); if (skb == tp->retransmit_skb_hint) tp->retransmit_skb_hint = NULL; if (skb == tp->lost_skb_hint) tp->lost_skb_hint = NULL; }}---------------------------------------------------------------------------------------int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size){ while (seglen > 0) { skb = tcp_write_queue_tail(sk); if (copynew_segment: /* Allocate new segment. If the interface is SG, * allocate skb fitting to single page. */ if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; skb = sk_stream_alloc_skb(sk, select_size(sk, sg), sk->sk_allocation); if (!skb) goto wait_for_memory; skb_entail(sk, skb); }}---------------------------------------------------------------------------------------debug kernel 3.13.1丢出的信息:[ 56.403621] sendto() len = 560[ 56.403628] tcp_sendmsg() 1210 skb->len = 560 tmp = 0![ 56.403635] ip_finish_output2() skb->len = 612[ 56.403724] sendto() len = 4095[ 56.403748] tcp_sendmsg() 1210 skb->len = 4095 tmp = 560![ 56.403756] ip_finish_output2() skb->len = 2948[ 56.403862] sendto() len = 4095[ 56.403880] tcp_sendmsg() 1210 skb->len = 5294 tmp = 2896!丢信息的代码如下:1.tcp.ctcp_sendmsg(){ while (seglen > 0) { struct sk_buff *tmp; tmp = skb->prev; printk("tcp_sendmsg() 1210 skb->len = %d tmp = %d!\n",skb->len,tmp->len);}2.ip_output.cstatic inline int ip_finish_output2(struct sk_buff *skb){ if (!IS_ERR(neigh)) { int res = 0; printk("ip_finish_output2() skb->len = %d\n",skb->len); res = dst_neigh_output(dst, neigh, skb); rcu_read_unlock_bh(); return res; }} 10-30 23:00