Chinaunix首页 | 论坛 | 博客
  • 博客访问: 690697
  • 博文数量: 192
  • 博客积分: 1875
  • 博客等级: 上尉
  • 技术积分: 2177
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-23 23:21
个人简介

有时候,就是想窥视一下不知道的东东,因为好奇!

文章分类

全部博文(192)

文章存档

2024年(8)

2023年(3)

2019年(1)

2018年(1)

2017年(2)

2016年(69)

2015年(53)

2014年(14)

2013年(1)

2012年(5)

2011年(25)

2010年(9)

分类: LINUX

2015-08-20 21:30:13

第十五章 发送和接收数据包
15.1 内核的发送/接收函数
        send()/recv(), sendto()/recvfrom(), sendmsg()/recvmsg()
        a. 以上函数经过glibc及内核的宏替换映射到sys_socketcall()系统调用的sys_send()/sys_sendto()/sys_sendmsg()/sys_recv()/sys_recvfrom()/sys_recvmsg()
        b. sys_send()-->sys_sendto()-->sock_sendmsg(). 即3对函数都集中在sock_sendmsg()和sys_recvmsg()
        c. write()/read()对应系统调用sys_write()/sys_read()-->vfs_write()/vfs_read()-->do_sync_write()/do_sync_read()-->sock_aio_write()/sock_aio_read()-->do_sock_write()/do_sock_read()-->......
        .....-->__sock_sendmsg()/__sock_recvmsg()
15.2 客户端发送数据包
        struct msghdr {
            ....
        };
        struct iovec {
            .....
        };
        struct sock_iocb {
            .....
        };
        __sock_sendmsg()-->tcp_sendmsg()-->tcp_write_queue_tail()
                                                                   -->tcp_send_head()
                                                                   -->select_size()缓冲区大小
                                                                   -->skb_entail()-->tcp_add_write_queue_tail()
                                                                   -->skb_add_data()
                                                                   -->skb_copy_to_page()-->sk_mem_charge()-->sk_has_account()
                                                                   -->forced_push()
                                                                   -->tcp_mark_push()
                                                                   -->__tcp_push_pending_frames()-->tcp_write_xmit()-->tcp_mtu_probe()
                                                                                                                                                      -->tcp_cwnd_test()-->tcp_packets_in_flight() 
                                                                                                                                                      -->tcp_event_new_data_sent()-->tcp_advance_send_head()
                                                                   -->tcp_send_head()
                                                                   --> tcp_push_one()-->tcp_init_tso_segs()-->tcp_set_skb_tso_segs()
                                                                                                  -->tso_fragment()-->tcp_fragment()-->skb_split()-->skb_split_inside_header()
                                                                                                                                                                               -->skb_split_no_header()
                                                                                                                              -->tcp_insert_write_queue_after()
                                                                                                  -->tcp_transmit_skb()
                                                                                                                                   
        tcp_sendmsg()完成数据包的发送
        tcp_write_queue_tail()获取sock发送队列中的数据包
        tcp_send_head()发送头指向的数据包
        select_size()缓冲区大小. 分配新的skb的数据包结构空间时
        skb_entail()将数据包链入到sock结构的发送队列
        tcp_add_write_queue_tail()将数据包链入sock发送队列的尾部
        skb_add_data()将客户端程序数据复制到缓冲块中,形成数据块.
        skb_copy_to_page()将应用程序数据复制到内存页面中
        forced_push()检查发送序号主是否在PUSH序号的最大范围内
        tcp_mark_push()设置PUSH标志. 将PUSH序号设置为发送序号
        __tcp_push_pending_frames()发送数据包
        tcp_send_head()是否急需发送的数据包?
        tcp_push_one()检查拥塞情况,分段发送数据包, 分段后的数据包留在发送队列, 下一次循环复制用户后发送
        tcp_init_tso_segs()初始化TSO分段数
        tso_fragment()将原数据包分段到新的数据包,并将新数据包链入到发送队列.
        tcp_fragment()数据包分段处理. 收缩原数据包,多余数据放在新数据包中.
        skb_split()分隔/转嫁超出部分到新数据包
        skb_split_inside_header()分隔基本数据块, 转嫁分散数据块到新数据包
        skb_split_no_header()将分散数据块转嫁/分隔到新数据包
        tcp_mtu_probe()检查MTU
        tcp_cwnd_test()计算阻塞限额. 根据窗口规定的阻塞要求计算还能发送的数据包数量.
        tcp_event_new_data_sent()准备发送下一数据包
        tcp_advance_send_head()调整发送头,使其指向下一个数据包.

            ......待深入理解

15.3 服务器接收数据包

阅读(1201) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~