免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: yulc
打印 上一主题 下一主题

linux下非阻塞的tcp研究 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
21 [报告]
发表于 2007-07-31 11:06 |只看该作者
原帖由 醉卧水云间 于 2007-7-31 11:03 发表
建议flw还是去补习一下网络编程吧,阻塞模式下,必须发到对端函数才返回。

请你自重。
你应该知道我非常不喜欢你。
你在 BSD 版撒泼让你失去了最后一次让我重新审视你的机会。

论坛徽章:
0
22 [报告]
发表于 2007-07-31 11:11 |只看该作者
send 本身在内核部分的代码就是TCP和网络程序的一部分。

看帖子:

http://bbs.chinaunix.net/viewthr ... =%CB%BC%D2%BB%BF%CB


本机发出的报文
(route if need)dev_queue_xmit |
ip_finish_output2 |<POSTROUTING> ip_finish_output | ip_output | ip_dst_output | <LOCALOUT> ip_push_pending_frames | raw_sendmsg | inet_sendmsg | sock_sendmsg | sys_sendmsg | sys_socketcall | sysenter_past_esp

调用启动和网络的许多函数。

也就是说socket write /send 和网络是在一起的,而没有一个清晰的buffer, send/write放入,网络程序取出那样的清晰的生产消费过程(虽然可以在一定程度上理解为生产/消费)

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
23 [报告]
发表于 2007-07-31 11:12 |只看该作者
继续讨论 TCP ....不要受其他干扰

论坛徽章:
38
2017金鸡报晓
日期:2017-02-08 10:39:4215-16赛季CBA联赛之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:2720周年集字徽章-周	
日期:2022-01-13 15:12:33
24 [报告]
发表于 2007-07-31 11:16 |只看该作者
原帖由 flw 于 2007-7-31 11:06 发表

请你自重。
你应该知道我非常不喜欢你。
你在 BSD 版撒泼让你失去了最后一次让我重新审视你的机会。


也请你自重,不知道不要乱说误导别人。

你也应该知道我非常不喜欢你,不要忘记是怎么卸掉本版斑竹的,你有生杀大权,我可以不要ID。

就凭你来审视我,笑话!你当你是老胡啊?想想你算老几再说这种居高临下的话吧,白写那么多代码,到头来连基本常识都不知道,真不知道你怎么写代码的,替你悲哀。

论坛徽章:
0
25 [报告]
发表于 2007-07-31 11:17 |只看该作者
原帖由 cookis 于 2007-7-31 09:45 发表
绝世好贴...
有一点不明白...

发送方也要用select吗..那岂不是每一次发送前都要用select轮循一下..我一般就是send 返回 -1就表示对方关闭(或网络中断)






通常tcp应用是需要交互的,所以在编程实现中,如果采用非阻塞方式,一般是用select来检测socket是否可读/可写的.
你总不能在非阻塞的状态下这样写吧,如果你不怕累死CPU的话.
while(1)
{
  send();
  if(err != EAGAIN)
    break;
  eles
    continue;
}

所以,一般是写成这样:
while(1)
{
  select();
  if(可读)
    read();
  if(可写)
    recv();
  ...
}

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
26 [报告]
发表于 2007-07-31 11:18 |只看该作者
原帖由 思一克 于 2007-7-31 11:11 发表
本机发出的报文
(route if need)dev_queue_xmit |
ip_finish_output2 |<POSTROUTING> ip_finish_output | ip_output | ip_dst_output | <LOCALOUT> ip_push_pending_frames | raw_sendmsg | inet_sendmsg | sock_sendmsg | sys_sendmsg | sys_socketcall | sysenter_past_esp

具体到这里,就是实现相关了,Linux 的实现一向以糟糕著称,没准儿等 2.8 又会变成什么样子,而且,对于应用层程序员来说,他看不到这些。
总而言之,从逻辑上来看,send/write 的作用,就是把数据放入发送缓冲区,然后返回。至于它如何通知 TCP 来发送,以及 TCP 又如何发送,发送结果是什么,都不影响 send/write 的语义。

论坛徽章:
0
27 [报告]
发表于 2007-07-31 11:18 |只看该作者
原帖由 flw 于 2007-7-31 09:51 发表
【在阻塞模式下,send函数的过程是将应用程序请求发送的数据通过socket尽能力发送到对方接收缓存中(并非对方应用程),并返回成功发送的大小;】

这句话是错的吧?
我认为即使是在阻塞方式下,只要发送缓冲区还 ...




这个你理解得不对,在阻塞模式下,send要保证发出的数据得到对端的ack确认后才会返回,也就是说当send返回时,请求发送的数据至少已经到达对端的接收缓存中.

论坛徽章:
0
28 [报告]
发表于 2007-07-31 11:19 |只看该作者
原帖由 flw 于 2007-7-31 09:59 发表
【如果发送应用程序没有处理这个可读的信号,而是继续调用send,那么第一次会像往常一样继续填充缓存区,然后返回,但如果再次调用send,进程会收到SIGPIPE信号,该信号的默认响应动作是退出进程.】

这个也不对。
我认为这个不是第一次还是第二次的问题,
而取决于发送端是否已经收到了对方的 FIN 包,
如果收到了就会 SIGPIPE 或者 EPIPE,
否则正常发送,不会出错。



我的测试结果是,当接收端主动关闭后,发送应用程序调用send,但在这个send之前,即使发送端已经收到了对方的FIN包,应用程序也不会得到SIGPIPE,而仅仅是返回-1的结果,同时,会将errno置为对端已关闭的那个宏(我不记得叫什么了),那么,如果应用程序傻傻的再调一次send,这时候,SIGPIPE产生了.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
29 [报告]
发表于 2007-07-31 11:21 |只看该作者
原帖由 醉卧水云间 于 2007-7-31 11:16 发表

也请你自重,不知道不要乱说误导别人。

你也应该知道我非常不喜欢你,不要忘记是怎么卸掉本版斑竹的,你有生杀大权,我可以不要ID。

就凭你来审视我,笑话!你当你是老胡啊?想想你算老几再说这种居高 ...

你自我感觉也太良好了吧?
以为我卸任本版版主是因为你逼的?
你不觉得你的声音在本帖里面很不和谐麽?

PS:我已经将你的回复加入 blacklist,请不要再向我回复,回了我也看不见。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
30 [报告]
发表于 2007-07-31 11:21 |只看该作者
原帖由 yulc 于 2007-7-31 11:19 发表

我的测试结果是,当接收端主动关闭后,发送应用程序调用send,但在这个send之前,即使发送端已经收到了对方的FIN包,应用程序也不会得到SIGPIPE,而仅仅是返回-1的结果,同时,会将errno置为对端已关闭的那个宏(我 ...

哦?把你的测试代码发上来。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP