免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3525 | 回复: 5
打印 上一主题 下一主题

[网络子系统] tcp中的send函数是何时返回的 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-05-16 09:04 |只看该作者 |倒序浏览
几乎所有介绍tcp socket中send函数的地方都会提到,send只是把数据拷贝到socket的发送队列就返回了,并不等待从网卡发送出去。按照这么理解的话应该有另外一个内核线程负责把数据从socket发送队列取出然后发送到网络上。
但是我在dev_hard_start_xmit调用了dump_stack(),通过查看函数栈发现send函数事实上一直调到了驱动注册的发送函数ndo_start_xmit。也就是说send是从网卡发送完成后才返回的。这个是不是有矛盾了呢?

[<ffffffff8161bdb8>] dev_hard_start_xmit+
[<ffffffff8161c318>] __dev_queue_xmit+0x3
[<ffffffff8161c510>] dev_queue_xmit+0x10/
[<ffffffff81654df9>] ip_finish_output+0x2
[<ffffffff81656248>] ip_output+0x58/0x90
[<ffffffff816559a5>] ip_local_out+0x25/0x
[<ffffffff81655d0a>] ip_queue_xmit+0x13a/
[<ffffffff8166c889>] tcp_transmit_skb+0x4
[<ffffffff8166cdfa>] tcp_write_xmit+0x10a
[<ffffffff8166da7e>] __tcp_push_pending_f
[<ffffffff8165f1b8>] tcp_sendmsg+0x118/0x
[<ffffffff81097508>] ? finish_task_switch
[<ffffffff81688a74>] inet_sendmsg+0x64/0x
[<ffffffff81312517>] ? apparmor_socket_se
[<ffffffff81601e2b>] sock_sendmsg+0x8b/0x
[<ffffffff8144c442>] ? n_tty_read+0x402/0
[<ffffffff81602371>] SYSC_sendto+0x121/0x
[<ffffffff8109ddf4>] ? vtime_account_user
[<ffffffff810210b5>] ? syscall_trace_ente
[<ffffffff81602d5e>] SyS_sendto+0xe/0x10
[<ffffffff81724f4f>] tracesys+0xe1/0xe6  

论坛徽章:
0
2 [报告]
发表于 2015-05-21 08:40 |只看该作者
怎么看不到回复呢

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
3 [报告]
发表于 2015-05-25 11:24 |只看该作者
没研究过linux tcp的实现,但感觉TCP应该有多个发送路径
1)异步路径肯定是有的,比如发送窗口变小的时候,这时候应该是写入队列的;
2)直接发送路径也应该存在,比如带有PSH标记的报文,期望stack尽快发送,会不会直接调用ip_xmit?

PS,感觉没有你说的内核线程存在,如果有的话,在ps/top里面应该有个[tcpd]啥的。
tcp的异步发送,要么是在接收ack的上下文,要么是在timer上下文完成的?

论坛徽章:
0
4 [报告]
发表于 2015-05-25 20:18 |只看该作者
回复 3# nswcfd

对于窗口变小的情况,如果是阻塞的,send会一直等待直到全部发送;如果是非阻塞,那就能发多少发多少,并且立即返回。所以从这个意义上来说,并不是存在异步的理由。

接受ack是由软中断线程完成,不可能它来发送,因为这样会引入延迟。也不可能在timer上下文,因为在大流量场景下会阻塞调度。
   

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
5 [报告]
发表于 2015-05-26 14:27 |只看该作者
回复 4# littlenewer
你是对的,确实那不是异步的理由。

之前看tcp_sendmsg里有些路径有skb_entail操作,就认为是1楼说的“发送队列”了。
仔细看了一下,tcp的sk->sk_write_queue应该是用来管理重传的。

论坛徽章:
1
IT运维版块每日发帖之星
日期:2016-07-14 06:20:00
6 [报告]
发表于 2015-07-28 20:21 |只看该作者
本帖最后由 ken1980 于 2015-07-29 15:02 编辑

tcp接收流程:tcp_v4_rcv->tcp_v4_do_rcv->tcp_rcv_established在收到tcp的ack确认包后->tcp_data_snd_check->tcp_push_pending_frames->_tcp_push_pending_frames发送缓冲区里的数据
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP