实验作业五:深入理解TCP协议及其源代码

TCP协议中 connect 及 bind、listen、accept 背后的三次握手

理论:

 如图所示,服务器在调用 listen 函数进行监听后,客户端嗲用 connect 函数来发送 SYN 报文,之后由服务器中的 TCP协议栈负责三次握手的交互过程,在连接

建立之后,服务器会在监听队列中添加一个成功的连接,直到达到由 backlog 参数设置的最大连接数。最后服务器会调用 accept 函数从监听队列中选择一条连接。

第一次握手:客户端发送 SYN=x到达服务器

第二次握手:服务器收到 SYN=x,于是发送 ACK=x+1 和 SYN=y 给客户端

第三次握手:客户端收到服务器的确认和同步,再返回给服务器一个确认,发送 ACK=y+1

三次握手完成后,客户端与服务器之间就建立了连接,此时服务器调用 accept 函数就可以得到此连接。

源代码阅读:

connect

 socket结构中的指针 ops 指向某个 proto_ops 数据结构,对于 tcp 来说,connect 会指向 inet_stream_connect(),该函数的代码在 net/ipv4/af_inet.c 中,其中部分代码:

sock->state 有许多,SS_CONNECTED 表示已经建立连接了,SS_CONNECTING 表示正在建立连接,SS_UNCONNECTED 表示还没有建立连接,也只有在此状态下,才能成功调用

connect 函数。其中 sk->sk_port->connect 这一句会调用 tcp_v4_connect 并发送 SYN 进行建立连接的操作。

tcp_v4_connect 函数在 net/ipv4/tcp_ipv4.c文件中,该函数比较复杂,它会首先设置好目的地址和目的端口号,然后设置状态,将传输控制添加到散列表并动态分布端口,此处涉及到一个函数 tcp_v4_hash_connect,等上述操作都完成后会更新路由,最后开始根须初始序号和当前时间,随机计算一个初始 id,然后调用 tcp_connect 函数,该函数构造并发送 SYN 段,该函数位于 net/ipv4/tcp_output.c 文件中,同样它也会调用一些初始化函数,但最后就是它将 SYN 发送了出去,部分代码:

listen

 注意其中的 sock->ops->listen 函数,该函数会调用 net/ipv4/af_inet.c 文件中的 inet_listen 函数,该函数的作用是:Move a socket into listening state。部分代码:

 对于已经处于监听状态的 socket,只允许改变其 backlog 参数的大小,即监听队列的长度;如果还没有处于监听状态,那么我们可以通过 inet_csk_listen_start 函数进入监听状态。

 参数 struct sock *sk 是TCP传输控制块,其中记录了包含与三次握手相关的一系列信息。

accept

accept 函数是在完成三次握手之后调用的,主要是 __sys_accept4 函数,它会调用 accept,就是 inet_accept,该函数会获得已经完成连接的传输控制块。

参考:

https://blog.csdn.net/m0_37875954/article/details/76946370

https://blog.csdn.net/m0_37875954/article/details/76851100

https://blog.csdn.net/m0_37875954/article/details/77018826

猜你喜欢

转载自www.cnblogs.com/vectorustc/p/12104214.html
今日推荐