Android TCP/IP常见问题

1 TCP的6种标识
SYN:SYNchronous,建立联机
ACK:ACKnowledgement,确认
PSH:PuSH,传送
FIN:FINish,结束
RST:ReSeT,重置
URG:URGent,紧急
SEQ:SEQuence number,顺序号码

2 TCP 3次握手
2.1 Wireshark抓包分析
Wireshark抓包时,3次握手显示的是相对序列号/确认号。如果想要关闭相对序列号/确认号,可以选择Wireshark菜单栏中的 Edit -> Preferences ->protocols ->TCP,去掉Relative sequence number后面勾选框中的√即可。

原始的Seq和ACK的值都很大,为便于理解,使用相对值;有点类似于真值表。
Seq, ACK
0, 0
0, 1
1, 1

3次握手Wireshark过滤规则:tcp.flags.syn==1 or tcp.flags.ack==0

2.2 Linux内核3次握手和接受数据状态机
RFC 793
net/ipv4/tcp_input.c
服务端 - tcp_rcv_state_process()
客户端 - tcp_rcv_synsent_state_process()

TCP server端完成最终的3次握手 - 一直处于TCP_LISTEN状态监听连接
in net/ipv4/tcp_minisocks.c
三次握手成功后,tcp_check_req()调用syn_recv_sock() -> tcp_v4_syn_recv_sock(),创建一个新的socket给accept()函数返回。
int tcp_child_process(struct sock *parent, struct sock *child, struct sk_buff *skb)

2.3 TCP探测socket断开
- SO_KEEPALIVE
- 用户层心跳机制

3 TCP 4次挥手
3.1 工作原理
@ net/ipv4/tcp.c
tcp_close() - 如果接收缓冲区中还有数据,协议栈就会发送RST而不是FIN

4次握手Wireshark过滤规则:tcp.flags.fin == 1

3.2 TIME_WAIT状态
TCP_TIMEWAIT_LEN:等待2MSL(Maximum Segment Lifetime,最大报文生存时间)后socket状态转换为CLOSED状态,MSL硬编码为30s

# FIN_WAIT1
# if this value is equal to 0, kernel chooses 8
echo 2 > /proc/sys/net/ipv4/tcp_orphan_retries

# TCP_FIN_TIMEOUT
echo 3 > /proc/sys/net/ipv4/tcp_fin_timeout
# TCP_TIMEWAIT_LEN
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

3.3 URLs
为何客户端突然出现大量TIME_WAIT堆积
https://zhuanlan.zhihu.com/p/63841157

4 TCP接收数据流程
@ net/ipv4/tcp_ipv4.c
tcp_v4_do_rcv()

@ net/ipv4/tcp_input.c
tcp_rcv_established()
tcp_validate_incoming()

TCP fast path只能处理ACK和PSH;如果TCP flag中有其它标志的必须走slow path,譬如有RST标志的一定走slow path

5 TCP ACK机制
5.1 ACK原理
TCP延时确认时间通常为40毫秒(#define TCP_DELACK_MIN ((unsigned)(HZ/25)))
icsk->icsk_ack.pingpong == 0,表示使用快速确认。
icsk->icsk_ack.pingpong == 1,表示使用延迟确认。

5.2 URLs
Linux下TCP延迟确认(Delay ACK)机制
https://blog.tms.im/2017/05/15/delay-ack.html

再探Linux下的TCP延迟确认机制
https://www.jianshu.com/p/6f795599e4ab

6 DHCP
DHCP Offer报文Options中包含了DNS Server地址

Android GB system/core/libnetutils/dhcp_utils.c
int dhcp_do_request(..., in_addr_t *dns1, in_addr_t *dns2...)

Android4.3前后DNS解析简单研究
https://blog.csdn.net/insswer/article/details/17382535

Android DHCP 启动分析【2】
http://blog.sina.cn/dpool/blog/s/blog_4a471ff601016cx7.html

7 FIB
路由表查找过程(ip_route_input_slow)
http://m.blog.chinaunix.net/uid-26874207-id-4894277.html
@ net/ipv4/route.c
ip_route_input()

8 TCP/IP二层设备类型
8.1 TUN and TAP
TUN/TAP:TUNnel / Network Terminal Access Point,TAP运行在链路层,主要用于虚拟机虚拟ethernet网络

- 对/dev/net/tun节点ioctl创建tap0网络
- /sys/class/net/tap0

8.2 BRIDGE
- 命令brctl

struct net_device {
    [...]
    struct net_bridge_port *br_port; 属于哪个网桥端口
    [...]
};

Linux网桥实现分析
http://m.blog.chinaunix.net/uid-29547110-id-5038812.html

8.3 VLAN
- 命令ip link
- VLAN在MAC桢头中增加了4个字节

9 网络线路规程qdisc
9.1 qdisc驱动队列
- num_tx_queues表示发送队列的个数,在创建网络设备时进行初始化
- tx_queue_len表示发送队列的最大长度,也即发送队列中正在排队的最大skb个数
- 网络的驱动队列由qdisc管理
net/sched/sch_generic.c
pfifo_fast_enqueue()默认的排队函数

Figure 9-1 Driver Queue

9.2 socket读写错误返回值
socket读写错误返回值:errno

10 常用调试命令
10.1 tcpdump
tcpdump -i eth0 icmp

10.2 traceroute
Windows 等效命令是tracert

10.3 TCP/UDP测试工具
busybox nc -lvz -s 172.16.0.99 -p 8001

10.4 ethtool
rxwen/ethtool
https://github.com/rxwen/ethtool

ifconfig -a
busybox route -n
iptables -L
ip6tables -L
busybox arp -a
ethtool -S eth0
netstat -apnt
netstat -apnu

10.5 ss
ss -tan state time-wait | wc -l

ss:Socket Statistics。ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。
ss快的秘诀在于,它利用到了TCP协议栈中tcp_diag。tcp_diag是一个用于分析统计的模块,可以获得Linux内核中第一手的信息,这就确保了ss的快捷高效。

发布了121 篇原创文章 · 获赞 47 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/zoosenpin/article/details/103933891
今日推荐