问一个关于数据接收的问题

oldn123 2010-04-26 01:17:30
LRESULT CClientDlg::OnSvrMsg01(WPARAM wParam,LPARAM lParam)
{
if(!mySocket.m_bConnect)return 0L;
if(WSAGETSELECTEVENT(lParam)!=FD_READ)return 0L;
if(mySocket.m_clientSocket!=wParam)return 0L;

mySocket.m_nLength=recv(mySocket.m_clientSocket,(LPSTR)mySocket.buf,sizeof(mySocket.buf),0);
if(mySocket.m_nLength>0)
{
m_ProcRecvData.OnRecvDataEx((LPBYTE)mySocket.buf, mySocket.m_nLength);
}
mySocket.Init();
return 0;
}


上面的函数是接收服务器端来的数据的事件响应代码,
这里我发现在我的OnRecvDataEx处理还未完成时,又有服务器端的消息了,从而把我的mySocket.buf中的数据给充成新的了,但是OnRecvDataEx中还没有对数据处理完..

这样的情况我需要在recv前加锁么?或者是应该怎样处理可以保证我的客户端可以在处理完该次的数据后再接收响应服务器传来的新的数据.

谢谢
...全文
214 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
liwei3290 2010-04-27
  • 打赏
  • 举报
回复
可以定义个结构体
typedef struct {
uint In;
uint Out;
uint size;
uchar *buffer;
} RING;

循环队列结构 ,给你点提示 ,如有兴趣 可联系liwei329044941@126.com讨论。
liwei3290 2010-04-27
  • 打赏
  • 举报
回复
建议用循环队列缓存,一边接收数据,一边从队列中取出数据来理
oldn123 2010-04-26
  • 打赏
  • 举报
回复
我这里没有太复杂的处理, 可能是因为解析数据时用了太多层递归弄的慢了一点.
找到问题了,刚才的代码只是buffer弄成异步的了,但是buffer len没改,所以新的数据来把这个len给我改了..导致了数据不对的问题
buptzwp 2010-04-26
  • 打赏
  • 举报
回复
处理速度忙于接收速度的话,弄个牛逼的处理器吧。
oldn123 2010-04-26
  • 打赏
  • 举报
回复
噢,还真是,如果一直处理不完那有数据来我就开内存, 内存会受不了..
丢数据不太好..来的数据都是要准备处理的.那就是只能优化处理速度了吧? 别让它卡在里面太久.
那上面的代码除了内存有这种开不出来的可能性外,其它方面应该是可以的吧?
快乐鹦鹉 2010-04-26
  • 打赏
  • 举报
回复
解决啥啊,早晚把内存搞暴了......
我说了,如果处理速度慢,你得给水池加其它出水口。比如数据丢弃策略(进水口加过滤器);比如多线程数据处理(出水口加粗)
oldn123 2010-04-26
  • 打赏
  • 举报
回复
好,那么现在假设是处理速度慢于接收的速度情况. 我上面的代码应该是可以解决这个才对的吧? 接收速度慢于处理速度就更不会出问题了
快乐鹦鹉 2010-04-26
  • 打赏
  • 举报
回复
缓存空间就像水池,如果处理速度大于数据接收速度,那么放心,稍大一些的空间即可。
如果处理速度慢于数据接收速度,那么麻烦了,也许你需要提高处理速度了,或者就需要考虑淘汰策略,让水池多加几个出水口,否则早晚溢出,再大的水池也没有用。
如果时快时慢,那么可以创建一个动态字符串数组,慢的时候就存下来,等快的时候自然就会处理掉。当然,设定一个最大长度是可取的。当出现最大长度时,就需要按照处理速度慢于数据接收速度的原则进行处理了。
oldn123 2010-04-26
  • 打赏
  • 举报
回复
哦,我这边还真没有什么特别的符号可以来作这个区分,服务器传来的都是数据,不是文本信息, 我刚改成用个buffer list 来接收的形式.



mySocket.m_nLength=recv(mySocket.m_clientSocket,(LPSTR)mySocket.buf,sizeof(mySocket.buf),0);
if(mySocket.m_nLength>0)
{
LPBYTE pBuffer = new BYTE[mySocket.m_nLength];
memcpy(pBuffer, (LPBYTE)mySocket.buf, mySocket.m_nLength);
m_bufferList.AddTail(pBuffer);
m_ProcRecvData.OnRecvDataEx(&m_bufferList, mySocket.m_nLength);


void CProcRecvData::OnRecvDataEx(CList<LPBYTE> * pBufferList, int nBufferLen)
{
EnterCriticalSection(&m_cs);
LPBYTE pTempBuffer = (LPBYTE)pBufferList->GetHead();
OnRecvData(pTempBuffer, nBufferLen);
delete[] pTempBuffer;
pTempBuffer = NULL;
pBufferList->RemoveHead();
LeaveCriticalSection(&m_cs);
}


这样改过后跑程序时还是出现了个数据信息不准确的问题,不知道和改过的这种接收模式有没有关系.
尹成 2010-04-26
  • 打赏
  • 举报
回复
主要是服务器控制。即使客户端加锁,服务器发送快,当缓冲区慢之后也会丢包的。所以你应该将每次接收到的内容加到这个buf的尾部,而不是替换。将buf定义的大一些。OnRecvDataEx时,将buf中前段的完整信息取走。比如一般的信息都以回车换行作为结尾,那么将buf中的信息每次取出最后一个回车换行符前的内容即可。如果没有特别的结尾,那么应该考虑建两个缓冲区,一个用来接收,保证能收下来,而不会被覆盖,另一个用来处理 。
快乐鹦鹉 2010-04-26
  • 打赏
  • 举报
回复
我这边是这么干的,收到的信息放到CString类型变量中。每次接收用一个BYTE数组接收,然后加入到CString中。每次收到信息,就将CString类型变量中最后一个回车换行符前的内容截取掉,发送给主线程处理。这样CString类型变量的内容就不可能很长,而且能将上次未传全的内容继续保留在CString类型变量中,可以和下次发上来的信息自然连接。
快乐鹦鹉 2010-04-26
  • 打赏
  • 举报
回复
不要感动。是CSDN出问题了才连续出现三次......
oldn123 2010-04-26
  • 打赏
  • 举报
回复
呵呵,鹦鹉大哥回了三次一样的真是让人感动啊..
==你这么处理不合适。你应该将每次接收到的内容加到这个buf的尾部,而不是替换。
--------
这是个办法, 但是buf一定要足够大才成吧?但是足够大不太好讲多大才合适了

弄缓冲区也可以,但是得弄成缓冲区的数组吧,两个也可能不够用,第一条没处理完呢,第三条消息又过来了就完蛋啦.

现在来看还是多搞些缓冲区自己控制一下吧.

如果还有其它什么好办法楼下的帮忙提一些出来.,谢谢
快乐鹦鹉 2010-04-26
  • 打赏
  • 举报
回复
又有服务器端的消息了,从而把我的mySocket.buf中的数据给充成新的了
==你这么处理不合适。你应该将每次接收到的内容加到这个buf的尾部,而不是替换。将buf定义的大一些。OnRecvDataEx时,将buf中前段的完整信息取走。比如一般的信息都以回车换行作为结尾,那么将buf中的信息每次取出最后一个回车换行符前的内容即可。
如果没有特别的结尾,那么应该考虑建两个缓冲区,一个用来接收,保证能收下来,而不会被覆盖,另一个用来处理
快乐鹦鹉 2010-04-26
  • 打赏
  • 举报
回复
又有服务器端的消息了,从而把我的mySocket.buf中的数据给充成新的了
==你这么处理不合适。你应该将每次接收到的内容加到这个buf的尾部,而不是替换。将buf定义的大一些。OnRecvDataEx时,将buf中前段的完整信息取走。比如一般的信息都以回车换行作为结尾,那么将buf中的信息每次取出最后一个回车换行符前的内容即可。
如果没有特别的结尾,那么应该考虑建两个缓冲区,一个用来接收,保证能收下来,而不会被覆盖,另一个用来处理
快乐鹦鹉 2010-04-26
  • 打赏
  • 举报
回复
又有服务器端的消息了,从而把我的mySocket.buf中的数据给充成新的了
==你这么处理不合适。你应该将每次接收到的内容加到这个buf的尾部,而不是替换。将buf定义的大一些。OnRecvDataEx时,将buf中前段的完整信息取走。比如一般的信息都以回车换行作为结尾,那么将buf中的信息每次取出最后一个回车换行符前的内容即可。
如果没有特别的结尾,那么应该考虑建两个缓冲区,一个用来接收,保证能收下来,而不会被覆盖,另一个用来处理
whs1980 2010-04-26
  • 打赏
  • 举报
回复
可不可以每次接收的时候都放到一块新的内存中,而不是只用同一块内存接收.
oldn123 2010-04-26
  • 打赏
  • 举报
回复
啊?加锁会导致丢包么?
服务器端我控制不了,不能去控制服务器端的
buptzwp 2010-04-26
  • 打赏
  • 举报
回复
还是服务器控制一下吧。即使客户端加锁,服务器发送快,当缓冲区慢之后也会丢包的。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧