免费注册 查看新帖 |

Chinaunix

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

[C++] SOCKET多线程向同一SOCKET发送数据,数据会出现互相重叠坏掉吗 [复制链接]

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
31 [报告]
发表于 2010-01-29 09:41 |只看该作者
原帖由 思一克 于 2010-1-29 09:12 发表
实际是流式SOCKET(TCP)即使建立一个2端的数据字节管道。一个管道用5元组(IP0, PORT0, IP1, PORT1, TCP不必要)表示的。
2个线程进程同时往同一个管道里放水,水有可能混合。

文件系统不许这样。
pipe仅仅 ...


曾经试过用非阻塞方式发送,发送缓冲区设置为1字节,一次性发送110M直接成功,一次性发送130M返回-1,这样看来128M就是一个槛,应该是调用send之后,数据一次性被拷贝至内核发送队列了,这样根据你的说法,是否可以理解为对于这样的系统,多线程发送数据小于128M的话,就不必担心数据错乱了呢?

论坛徽章:
0
32 [报告]
发表于 2010-01-29 09:48 |只看该作者
原帖由 w_anthony 于 2010-1-29 09:41 发表


曾经试过用非阻塞方式发送,发送缓冲区设置为1字节,一次性发送110M直接成功,一次性发送130M返回-1,这样看来128M就是一个槛,应该是调用send之后,数据一次性被拷贝至内核发送队列了,这样根据你的说法, ...


不是。
小的数据块也可能乱。
十分小的,远小于MTU的比如512字节的块,乱的机会很小。

论坛徽章:
0
33 [报告]
发表于 2010-01-29 09:48 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
34 [报告]
发表于 2010-01-29 10:02 |只看该作者
原帖由 houhulou 于 2010-1-29 08:48 发表
感谢各位的回复, 我现在是两个线程对同一个SOCKET操作, 一个收 一个发, 如果收的在3秒内收不到任何数据,就会发送一个心跳包到对方, 这个心跳包有可能跟发送线程的发送数据造成交叉了, 这个问题大家是如何解决的 ...


你所担心的收发会出现数据交叉,是因为你用两个线程对同一个socket做可能的同时写操作。先不说是否会出现交叉,先分析下你的应用。
你两种情况下发数据,一是来请求来了给回应,二是3秒内没请求则发心跳。
这样的应用没必要用两个线程,纯属自己找麻烦啊。用select加3秒超时即可,3秒超时则发心跳,否则给请求反馈数据。

论坛徽章:
0
35 [报告]
发表于 2010-01-29 10:45 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
36 [报告]
发表于 2010-01-29 15:21 |只看该作者

回复 #35 houhulou 的帖子

发送线程能否这样,不管接收线程有没有收到数据,每隔3秒发送一个心跳。一般情况下接收端收到心跳也是直接丢弃的嘛。

如果上面的方法不行的话,那估计只能加线程锁了,原来在AIX上遇到过和你同样的问题,最后加锁解决了。。

论坛徽章:
0
37 [报告]
发表于 2010-01-30 14:21 |只看该作者
发送数据的时候,操作系统会自己加锁,sys_send 函数会调用get_futex_key在内核堆栈中看到的

[ 本帖最后由 独臂剑客 于 2010-1-30 19:25 编辑 ]

论坛徽章:
0
38 [报告]
发表于 2010-01-30 16:43 |只看该作者
原帖由 独臂剑客 于 2010-1-30 14:21 发表
int send( SOCKET s,    const char FAR *buf,    int len,    int flags );  

不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。

客户程序一般用send函数向服务器发送请求,而服务 ...


[
这里只描述同步Socket的send函数的执行流程。当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完
]

对于同步SOKET, 你这个说法是错误的。
SNDBUF一般仅仅有几十K, 你不能一次send大于这个数值的数据了?
你自己编写个程序实验,看能否。是能够的。一个SEND调用发送100M的数据块也可以。

还有,你还可以实验,2个进程写同一个SOCKET, 接收端数据混合的乱七八糟的情况。

论坛徽章:
0
39 [报告]
发表于 2010-01-30 18:26 |只看该作者
原帖由 思一克 于 2010-1-30 16:43 发表


[
这里只描述同步Socket的send函数的执行流程。当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于 ...



【send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度】
send函数中len长度解释确实有错误,net.core.rmem_max的值网络层默认应该是64K,传输层应该是128K。刚才试了一下,send大数据不会返回错误,send函数在发送大数据里本身应该做了处理。

不同线程/进程 发送数据接收乱的情况?这种情况需要上层去保证,比如为一个fd开一个buf,不同线程/进程向fd再送数据时,开始进的是buf,进buf时用锁保证好顺序,发送时再从buf一个一个发,不管你几个线程/进程发都没有问题。

内核send只是保证你不同线程/进程给它数据的时候,不会发生死锁情况。数据顺序以及其它方面需要上层去保证。

[ 本帖最后由 独臂剑客 于 2010-1-30 19:35 编辑 ]

论坛徽章:
0
40 [报告]
发表于 2010-01-31 18:10 |只看该作者
有这么用的需要的吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP