最后更新:2021-11-18 05:35
1. 应用层
1.1 server
socket() -> bind() -> listen() -> accept() -> recv() & send()
1.2 client
socket() -> connect() -> send() & recv()
为了连接,用一个13握手。


(1) 客户发送一个SYN段落(SYN符号位置),其初始序列号ISN,序列号为237945432343,在此过程中,客户使用连接功能提出连接请求,此后连接功能暂停,直到服务器提供ACK响应。
(2) 从服务器端接收SYN后(通过监听监听),服务器初始化了ISN序列号,在所举的例子中,该序列号为后号=4269857;此时,服务器构造了一个TCP段,插入SYN和ACK标记,使后号=4269857, ack=23794533244,然后将TCP段传送给客户。这一阶段完全内核完成,这一连接被添加到未完成的队列中。
(3) 客户再次从服务器收到TCP部分后,与SYN和ACK信号核对,以确保客户的连接已经建立,连接功能在那个时候返回。客户准备一个TCP段落,其中包括ACK标志,并将按键值设定为4269858,并将其发送到服务器。
(4) 服务器收到客户的ACK后,将这一连接与完成的连接队列连接(接受)。
二. 核心程序
2.1 客户端通过合同发送SYN电文,以建立与服务器的TCP连接。
connect ----> SYSCALL_DEFINE3(__sys_connect)(socket.c) -> sock->ops->connect -> inet_stream_connect(af_inet.c) -> __inet_stream_connect -> sk->sk_prot->connect -> tcp_v4_connect(tcp_ipv4.c) -> tcp_connect(tcp_output.c) -> tcp_send_syn_data | tcp_transmit_skb(syn)
tcp_connect(): Build a SYN and send it off
等待随后握手完成封锁电话;等待无阻断电话,立即返回EINPROGRESS,然后记录插座的连接、读和写,以及触发操作的异常点。
tcp_rcv_state_ process 2.2(三握手)
网卡驱动 --> netif_receive_skb - --> ip_rcv ---> ip_local_deliver_finish ---> tcp_v4_rcv -> tcp_v4_do_rcv -> tcp_rcv_state_process
1) client
客户收到SYN+ACK的讯息,并返回到ACK状态。
case TCP_SYN_SENT: tcp_rcv_synsent_state_process -> tcp_finish_connect & tcp_send_ack
client tcp state: CLOSING -> TCP_SYN_SENT -> TCP_ESTABLISHED
2) server
收到用户用户SYN邮件,发送SYN+ACK邮件
case TCP_LISTEN: icsk->icsk_af_ops->conn_request -> tcp_v4_conn_request -> tcp_conn_request -> af_ops->send_synack -> tcp_v4_send_synack
tcp_v4_send_synack(): Send a SYN-ACK after having received a SYN.
TCP_NEW_SYN_RECV 从服务器的 tcp 状态改为 TCP_NEW_SYN_RECV 。
b. 收到了客户的贺电。
建立这一联系是为了恢复休眠接受功能。
开始在 tcp_v4_rcv 中,在 TCP_SYN_RECV 状态中创建新袜子;
然后调用tcp_child_process -> tcp_rcv_state_process,最终进入TCP_ESTABLISHED状态,并放入accept队列通知select/epoll。
server tcp state: CLOSING -> TCP_LISTEN -> TCP_NEW_SYN_RECV -> TCP_SYN_RECV -> TCP_ESTABLISHED
2.3 服务器开始通过监听功能监听,届时可以接受阴蒂连接请求。
listen ----> SYSCALL_DEFINE2(listen) -> __sys_listen -> sock->ops->listen ---> inet_csk_listen_start
2.4 accept
接受 () 没有太多实际事件, 其功能是返回一个连接到的套接字( 即三个握手), ccept () 不亲自处理三次握手, 但只听 icsk_ compt_ queue 队列, 当手抖三次后, 就会被添加到 icsk_ compt_ queue 中, 所以要做什么 ccept 要做的就是等待在队列中插入套接字, 然后醒来然后返回这个套接字 。 并且三只握手的过程完全由协议本身来完成 。 换句话说, 协议的柜台相当于作者, 套接字写到队列中, 接受( ) 等同读者, 接字从队列中读出。 程序从听开始, 所以即使不打电话接受 () 客户仍然可以连接到服务器, 但是由于缺少处理, 排队列会很快被完全占用 。
2.5 bind
绑定操作的主要作用是将生成的套接字连接到所提供的地址, 这样创建的服务可以公开供外部调用。 当然, 套接字服务器的形成不需要这一步骤, 而对于听器 () 来说, 如果没有固定地址, 系统会随机选择一个可用的地址作为服务器的地址 。
本文由 在线网速测试 整理编辑,转载请注明出处。