0
点赞
收藏
分享

微信扫一扫

44 | Socket内核数据结构

小猪肥 2021-09-25 阅读 47
  • socket_create:创建一个 struct socket 结构,然后通过 sock_map_fd 和文件描述符对应起来。
    • 参数:
      • family:表示地址族。
      • type:也即 Socket 的类型。
      • protocol:是协议。
  • bind 函数:sockfd_lookup_light 会根据 fd 文件描述符,找到 struct socket 结构。然后将 sockaddr 从用户态拷贝到内核态,然后调用 struct socket 结构里面 ops 的 bind 函数,即调用 inet_bind。bind 里面会调用 sk_prot 的 get_port 函数,也即 inet_csk_get_port 来检查端口是否冲突,是否可以绑定。如果允许,则会设置 struct inet_sock 的本方的地址 inet_saddr 和本方的端口 inet_sport,对方的地址 inet_daddr 和对方的端口 inet_dport 都初始化为 0。
  • listen 函数:我们还是通过 sockfd_lookup_light,根据 fd 文件描述符,找到 struct socket 结构。接着,我们调用 struct socket 结构里面 ops 的 listen 函数也即调用 inet_listen。 这里面建立了一个新的结构 inet_connection_sock,客户端和服务端都是有一个结构维护连接的状态,就是指这个结构。
  • accept 函数:原来的 socket 是监听 socket,这里我们会找到原来的 struct socket,并基于它去创建一个新的 newsock。这才是连接 socket。除此之外,我们还会创建一个新的 struct file 和 fd,并关联到 socket。
  • conect 函数:三次握手过程:
    • 通过 tcp_v4_connect函数,查询路由表,选择从那个网卡出去。然后将状态置为TCP_SYN_SEND,然后初始化TCP 的 seq num,也即 write_seq,然后调用 tcp_connect 进行发送SYN 包。
    • 服务端处理函数 tcp_rcv_state_process ,根据不同的状态回应请求,由于当前服务端在TCP_LISTEN状态,会调用 tcp_v4_send_synack,服务端将状态改为TCP_SYN_RECV并发送SYN_ACK保存。
    • 客户端到 tcp_rcv_state_process ,由于客户端处于 TCP_SYN_SEND,会调用 tcp_send_ack,然后将客户端状态改为TCP_ESTABLISHED,然后发送ACK-ACK包。
    • 服务端到tcp_rcv_state_process,由于服务端处于TCP_SYN_RECV状态,将状态转为TCP_ESTABLISHED,然后就可以将这个连接放到就绪队列然后接收请求。
举报

相关推荐

0 条评论