用CSocket的派生类通讯,在接受一段时间后就不能出发OnReceive事件了,但这个Socket仍可发送?

时间:2021-10-08 16:56:58
用CSocket的派生类通讯,在接受一段时间后就不能触发OnReceive事件了,但这个Socket仍可发送?想知道产生的原因,和结决的方法。我的接收和发送是长时间运行的。

46 个解决方案

#1


接收缓存区域是不是都及时收走了?

#2


如何判断接收缓存区域是不是都及时收走了?如何保证接收缓存区及时收走?

#3


UP

#4


在响应onreceive时,循环调用receive,直到返回-1,buff才取完

#5


我收发的是CString形的变量,具体方法如下:
pClient->Send(inheritence.GetBuffer(length),inheritence.GetLength());
inheritence.ReleaseBuffer();

pSocket->Receive(inheritence.GetBuffer(length),length,0);
inheritence.ReleaseBuffer();

这会有问题吗,特别是发送的时候没有inheritence.ReleaseBuffer();会不会有问题?

#6


up

#7


up

#8


我测试了一夜,发现果然是收发CString 造成的,好像长时间的收发CString 就会出现问题,不知道是什么原因?

#9


Quote:MSDN

The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept, and then after a send fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will find out that sends are again possible when an FD_WRITE network event is recorded and the associated event object is set.

#10


还是不太明白?

#11


我也遇到了同楼主相同的问题,首先UP一下!
另:receive()返回-1是只意味着buffer缓冲取完呢,还是意味着接收失败?我如何才能保证在每次接收数据前将buffer清空呢?若socket接收失败,如何再恢复此socket继续接收?
望高手指点,谢谢!

#12


在CSting 操作的地方设置断点,跟踪一下,也许能找出问题的根源

#13


gz

#14


问题的根源很不容易找,要好长时间才会出现这个问题,怎么解决?

#15


up

#16


必须要ReleaseBuffers才可以的。你可以先用 (char *) 测试,首先要排除 CSting 的问题。

#17


(char *) 也测试过了,还是会出现不能接收的毛病

#18


关键是如何检测到这个错误的发生,我用getlasterror好像逮不到这个错误,要是能解释一下这个错误产生的原因也行.:-(

#19


好像收发别的如int型的值就没问题,是不是不宜长时间收发CString或char啊?

#20


你直接定义成char a[buflen]不就可以了嘛

#21


是不是一旦程序因为其他原因被阻塞了一会(6秒左右,期间一直会有数据传来),就会使接收缓存变满,从而导致以后不能再接收新数据,但不影响发送.
不过似乎循环接收(主要是保证全部收完每次发的包)也无法避免收缓存变满,而且一旦变满后也无法再清空并继续正常工作,是不是这样啊?

#22


Up

#23


mark

#24


OnReceive是个框架函数。如果这个函数不被调用了,那说明线程的消息分发被阻塞了。
你检查一下,看看是否有阻塞线程的东西。

#25


最新发现,没有了阻塞还是出现了只能发,不能收的情况:(

#26


gz~~

#27


等待ing

#28


up

#29


upup

#30


gz

#31


确保你的每一次接收都将缓冲区取完,如有一次接收不干净以下的onreceive将不被调用。可检查接收缓冲区的大小,注意避免与接收数据大小相同(可远远大于),如能用串行化可避免该问题。

#32


"如有一次接收不干净以下的onreceive将不被调用",确实是这样吗?欢迎大家发表意见:)

#33


我觉得你这样循环发送和接收不够好,应该用到一些同步信息来保证接收信息的连续性。(如果你要象UDP这样的传输方式的话除外。)因为TCP是流式而非帧式,要有上层确保数据的完整性的。

#34


我还在等待中,希望有一个圆满的解释^_^

#35


确实是一个很重要的问题,顶

#36


up

#37



“在响应onreceive时,循环调用receive,直到返回-1,buff才取完”
同意这种看法,收到的东西不是一下子就接受完的
你send一次,recv的数据不一定一次就接受完,就会存在队列里
这样积累下去多大的队列也会满啊

#38


“在响应onreceive时,循环调用receive,直到返回-1,buff才取完”
不同意这样的看法,如果是异步模式的话,你可能收到的信息是这次不该收的,应该设计上层保证数据的接收大少。

#39


继续讨论吧,但请结合我的问题:
似乎循环接收(主要是保证全部收完每次发的包)也无法避免收缓存变满,而且一旦变满后也无法再清空并继续正常工作,是不是这样啊?

#40


我也遇到这样的问题,也是用CString,我每一次发都是一小点的数据,收的时候肯定是全部清空缓冲区了,但是过一段时间后,OnReceive就不再调用了,直到下一次连接再建立,再发送后,才把上一次的数据取出来。不明白是什么原因?

#41


发送的时候记得用Flush()。

#42


To stoneyrh():你解决了吗?
To whgoplayer() :Flush()是在串行化传输时采用的,我这里还没用到

#43


今天终于找了答案,不过可能不适合你
我原来以为是接收不到数据的,后来发现并不是接收不到
而是我显示的时候用的是滚动视图,在设置滚动大小的初始值时出了一点问题,导致显示的时候最后一个字符没有显示出来

现在改过来了,正常。

#44


啊哦^*^

#45


再等等再结帖!

#46


采用串行化的方式能否保证发送和收缓存区及时的被清空?

#1


接收缓存区域是不是都及时收走了?

#2


如何判断接收缓存区域是不是都及时收走了?如何保证接收缓存区及时收走?

#3


UP

#4


在响应onreceive时,循环调用receive,直到返回-1,buff才取完

#5


我收发的是CString形的变量,具体方法如下:
pClient->Send(inheritence.GetBuffer(length),inheritence.GetLength());
inheritence.ReleaseBuffer();

pSocket->Receive(inheritence.GetBuffer(length),length,0);
inheritence.ReleaseBuffer();

这会有问题吗,特别是发送的时候没有inheritence.ReleaseBuffer();会不会有问题?

#6


up

#7


up

#8


我测试了一夜,发现果然是收发CString 造成的,好像长时间的收发CString 就会出现问题,不知道是什么原因?

#9


Quote:MSDN

The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept, and then after a send fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will find out that sends are again possible when an FD_WRITE network event is recorded and the associated event object is set.

#10


还是不太明白?

#11


我也遇到了同楼主相同的问题,首先UP一下!
另:receive()返回-1是只意味着buffer缓冲取完呢,还是意味着接收失败?我如何才能保证在每次接收数据前将buffer清空呢?若socket接收失败,如何再恢复此socket继续接收?
望高手指点,谢谢!

#12


在CSting 操作的地方设置断点,跟踪一下,也许能找出问题的根源

#13


gz

#14


问题的根源很不容易找,要好长时间才会出现这个问题,怎么解决?

#15


up

#16


必须要ReleaseBuffers才可以的。你可以先用 (char *) 测试,首先要排除 CSting 的问题。

#17


(char *) 也测试过了,还是会出现不能接收的毛病

#18


关键是如何检测到这个错误的发生,我用getlasterror好像逮不到这个错误,要是能解释一下这个错误产生的原因也行.:-(

#19


好像收发别的如int型的值就没问题,是不是不宜长时间收发CString或char啊?

#20


你直接定义成char a[buflen]不就可以了嘛

#21


是不是一旦程序因为其他原因被阻塞了一会(6秒左右,期间一直会有数据传来),就会使接收缓存变满,从而导致以后不能再接收新数据,但不影响发送.
不过似乎循环接收(主要是保证全部收完每次发的包)也无法避免收缓存变满,而且一旦变满后也无法再清空并继续正常工作,是不是这样啊?

#22


Up

#23


mark

#24


OnReceive是个框架函数。如果这个函数不被调用了,那说明线程的消息分发被阻塞了。
你检查一下,看看是否有阻塞线程的东西。

#25


最新发现,没有了阻塞还是出现了只能发,不能收的情况:(

#26


gz~~

#27


等待ing

#28


up

#29


upup

#30


gz

#31


确保你的每一次接收都将缓冲区取完,如有一次接收不干净以下的onreceive将不被调用。可检查接收缓冲区的大小,注意避免与接收数据大小相同(可远远大于),如能用串行化可避免该问题。

#32


"如有一次接收不干净以下的onreceive将不被调用",确实是这样吗?欢迎大家发表意见:)

#33


我觉得你这样循环发送和接收不够好,应该用到一些同步信息来保证接收信息的连续性。(如果你要象UDP这样的传输方式的话除外。)因为TCP是流式而非帧式,要有上层确保数据的完整性的。

#34


我还在等待中,希望有一个圆满的解释^_^

#35


确实是一个很重要的问题,顶

#36


up

#37



“在响应onreceive时,循环调用receive,直到返回-1,buff才取完”
同意这种看法,收到的东西不是一下子就接受完的
你send一次,recv的数据不一定一次就接受完,就会存在队列里
这样积累下去多大的队列也会满啊

#38


“在响应onreceive时,循环调用receive,直到返回-1,buff才取完”
不同意这样的看法,如果是异步模式的话,你可能收到的信息是这次不该收的,应该设计上层保证数据的接收大少。

#39


继续讨论吧,但请结合我的问题:
似乎循环接收(主要是保证全部收完每次发的包)也无法避免收缓存变满,而且一旦变满后也无法再清空并继续正常工作,是不是这样啊?

#40


我也遇到这样的问题,也是用CString,我每一次发都是一小点的数据,收的时候肯定是全部清空缓冲区了,但是过一段时间后,OnReceive就不再调用了,直到下一次连接再建立,再发送后,才把上一次的数据取出来。不明白是什么原因?

#41


发送的时候记得用Flush()。

#42


To stoneyrh():你解决了吗?
To whgoplayer() :Flush()是在串行化传输时采用的,我这里还没用到

#43


今天终于找了答案,不过可能不适合你
我原来以为是接收不到数据的,后来发现并不是接收不到
而是我显示的时候用的是滚动视图,在设置滚动大小的初始值时出了一点问题,导致显示的时候最后一个字符没有显示出来

现在改过来了,正常。

#44


啊哦^*^

#45


再等等再结帖!

#46


采用串行化的方式能否保证发送和收缓存区及时的被清空?