IOCP 多线程 接收 有关问题
IOCP 多线程 接收 问题
问个问题,用iocp,多线程模式下接受的时候会乱序吗?就比如一个连接先后发了两次数据:1:abcdef 2:hijklm;
然后接受到的时候,会不会是abcklmdefhij呢?如果会,如何解决。如果不会,原因是什么?粘包好解决,就是这乱序。。。。另外这种乱序我在实验过程中没出现过,但是理论上可能会出现吧,我说的对吗?敬请帮助!
------解决方案--------------------
帮顶下!!!好像是同步互斥问题吧!
------解决方案--------------------
是的, 如果是多线程的话, 可能会乱序, 应该为每个封包加一个序列
------解决方案--------------------
如果你能保证 发送端发送数据是有序的,那么到达接受端缓冲区内,
数据都是有序的,不会乱序,这是TCP协议规定的
------解决方案--------------------
多Thread接收也不会错的
除非你同时,向一个SOCKET 发送2个Recv请求。但是如果出现这种情况你是
应该将后一个Recv排队的等待第一个Recv完成,之后在发送Recv请求
------解决方案--------------------
还加什么序号?
理论上TCP不可能会乱序的。
------解决方案--------------------
排队 Recv请求
------解决方案--------------------
排队recv?!
同时多同一连接发起多个recv异步操作没有意义,而且导致程序逻辑混乱
一个连接同时只需要有一个recv操作即可,每次异步的recv完成再发起下一次的recv请求。
------解决方案--------------------
不明白为什么要多个线程里接受来自同一个端口的数据,这样能给你带来什么?
------解决方案--------------------
是可以提高效率:因为不用线程收一个,再投下一个WSARECV();
CPU就调用一次就可以接收两次的数据了.
------解决方案--------------------
------解决方案--------------------
服务线程和CUP的多少有关系。
这样才能使用CUP工作的更好
------解决方案--------------------
------解决方案--------------------
投递一次请求 等这个请求完成后再投递下一个请求 即使是多线程也不会乱序
------解决方案--------------------
我不明白的是发送的时候 是不是等上一个发送成功了 再投递 还是不必理上一个发送 我看BOOST的ASIO 好像可以连续投递发送
不敢确定
------解决方案--------------------
在一个连见上同时投递多个请求的问题:
其实无论你投递多少个请求,在最下面也是顺序完成请求的,
一般情况下你会发现你的数据都会如你所愿的接受回来,不会存在多大问题
但是有一个种情况你是很难处理的,在Recv端同时投递A,B2个请求, Client端发送
1000字节数据,结果地层接受到 500字节的时候缓冲区满了,
这个时候,你第一个请求A会顺利的返回,但是接受到的字节是 500个,也就是你
还要继续发送请求C才能接,受到剩余的数据,但是这个时候 你在发送一个请求
C的话,那么这个请求会被排在第二个请求B的后面,也就是说B会把剩余的500字
节接收回来.
还有IOCP的设计目的,是处理海量连接,而不是在单连接的数据处理效率
------解决方案--------------------
------解决方案--------------------
你再往同一个缓存里面写,就接着刚才已经写了的位置写喽,不然从缓冲区的头开始写,不就吧刚才写的东西冲掉了?
这个和粘包处理的方法一样嘛
------解决方案--------------------
假如同一时刻只有一个 recv I/O 操作在等待,不会有乱序的问题;
假如同一时刻有一个以上的 recv I/O 操作在等待,则所有正在等待的操作在数据到达时,它们的完成顺序以它们被投递时的顺序为依。两种情况均与线程无关。
情况一:
任何一个线程在处理完成的recv I/O 操作时,在处理完成之前不投递下一个recv I/O ,这能保证同一时刻只有一个 recv I/O 操作在等待。
情况二:
可能同时投递了一个以上的recv I/O,但无论如何,这个“同时”对IOCP来说还是有先后顺序的,IOCP对投递的未完成操作是以先进先出的顺序来满足完成状态的。要避免多个完成的I/O操作返回时无法确认它们的先后顺序,那么在投递I/O时,可以在与I/O关联的数据中填写该I/O的投递顺序号,这样该I/O返回时,就可以根据该顺序号来确定它的完成时间位置。与I/O关联的数据,即 通常所说的单I/O数据。
------解决方案--------------------
6楼说的没错,关键就是每次只投递一个recv请求
问个问题,用iocp,多线程模式下接受的时候会乱序吗?就比如一个连接先后发了两次数据:1:abcdef 2:hijklm;
然后接受到的时候,会不会是abcklmdefhij呢?如果会,如何解决。如果不会,原因是什么?粘包好解决,就是这乱序。。。。另外这种乱序我在实验过程中没出现过,但是理论上可能会出现吧,我说的对吗?敬请帮助!
------解决方案--------------------
帮顶下!!!好像是同步互斥问题吧!
------解决方案--------------------
是的, 如果是多线程的话, 可能会乱序, 应该为每个封包加一个序列
------解决方案--------------------
如果你能保证 发送端发送数据是有序的,那么到达接受端缓冲区内,
数据都是有序的,不会乱序,这是TCP协议规定的
------解决方案--------------------
多Thread接收也不会错的
除非你同时,向一个SOCKET 发送2个Recv请求。但是如果出现这种情况你是
应该将后一个Recv排队的等待第一个Recv完成,之后在发送Recv请求
------解决方案--------------------
还加什么序号?
理论上TCP不可能会乱序的。
------解决方案--------------------
排队 Recv请求
------解决方案--------------------
排队recv?!
同时多同一连接发起多个recv异步操作没有意义,而且导致程序逻辑混乱
一个连接同时只需要有一个recv操作即可,每次异步的recv完成再发起下一次的recv请求。
------解决方案--------------------
不明白为什么要多个线程里接受来自同一个端口的数据,这样能给你带来什么?
------解决方案--------------------
是可以提高效率:因为不用线程收一个,再投下一个WSARECV();
CPU就调用一次就可以接收两次的数据了.
------解决方案--------------------
------解决方案--------------------
服务线程和CUP的多少有关系。
这样才能使用CUP工作的更好
------解决方案--------------------
------解决方案--------------------
投递一次请求 等这个请求完成后再投递下一个请求 即使是多线程也不会乱序
------解决方案--------------------
我不明白的是发送的时候 是不是等上一个发送成功了 再投递 还是不必理上一个发送 我看BOOST的ASIO 好像可以连续投递发送
不敢确定
------解决方案--------------------
在一个连见上同时投递多个请求的问题:
其实无论你投递多少个请求,在最下面也是顺序完成请求的,
一般情况下你会发现你的数据都会如你所愿的接受回来,不会存在多大问题
但是有一个种情况你是很难处理的,在Recv端同时投递A,B2个请求, Client端发送
1000字节数据,结果地层接受到 500字节的时候缓冲区满了,
这个时候,你第一个请求A会顺利的返回,但是接受到的字节是 500个,也就是你
还要继续发送请求C才能接,受到剩余的数据,但是这个时候 你在发送一个请求
C的话,那么这个请求会被排在第二个请求B的后面,也就是说B会把剩余的500字
节接收回来.
还有IOCP的设计目的,是处理海量连接,而不是在单连接的数据处理效率
------解决方案--------------------
------解决方案--------------------
你再往同一个缓存里面写,就接着刚才已经写了的位置写喽,不然从缓冲区的头开始写,不就吧刚才写的东西冲掉了?
这个和粘包处理的方法一样嘛
------解决方案--------------------
假如同一时刻只有一个 recv I/O 操作在等待,不会有乱序的问题;
假如同一时刻有一个以上的 recv I/O 操作在等待,则所有正在等待的操作在数据到达时,它们的完成顺序以它们被投递时的顺序为依。两种情况均与线程无关。
情况一:
任何一个线程在处理完成的recv I/O 操作时,在处理完成之前不投递下一个recv I/O ,这能保证同一时刻只有一个 recv I/O 操作在等待。
情况二:
可能同时投递了一个以上的recv I/O,但无论如何,这个“同时”对IOCP来说还是有先后顺序的,IOCP对投递的未完成操作是以先进先出的顺序来满足完成状态的。要避免多个完成的I/O操作返回时无法确认它们的先后顺序,那么在投递I/O时,可以在与I/O关联的数据中填写该I/O的投递顺序号,这样该I/O返回时,就可以根据该顺序号来确定它的完成时间位置。与I/O关联的数据,即 通常所说的单I/O数据。
------解决方案--------------------
6楼说的没错,关键就是每次只投递一个recv请求