CSocket多线程的几个问题

luckyboy1979 2010-06-08 04:16:53
用CSocket来写的Server端和Client端程序。Server和Client都是多线程(UI线程)。
Server端在界面输入将有几个Client会连入Server,就启动几个UI线程。UI程序是继承CWinThread的。在UI线程中启动侦听,每个UI线程侦听的端口号是不一样的。每一个UI线程负责一个客户端数据的收发。
Client端运行后在执行与服务器连接时先启动一个UI线程,在UI线程中创建socket与服务器进行连接,socket收发数据也都是在UI线程中执行。
一个Client在与服务器建立链接后,Server程序中负责该Client的UI线程就不停地向Client发送BMP数据(一组25个BMP,一个BMP22K)。Server每次发送20K,在Server端进行数据拼接,每组一次都发满20K(最后一个可能没有20K)Server每Send一次Sleep(10)。在Client解包、校验数据,数据正确将一组BMP数据放入接收缓冲区中,校验不通过请求Server重发这组中接收错误的数据。Client有一个工作者线程将缓冲区中的数据写文件,写完一组从缓冲区中删除已写的数据。
Client接收数据的缓冲区用CRITICAL_SECTION进行保护。
Client每收完一组数据向Server发一个请求下一组数据的消息,Server才开始发下一组数据。
Client在开始接收数据时将负责Socket的UI线程的优先级提高到THREAD_PRIORITY_HIGHEST,Server端数据发送结束再将线程优先级降低到THREAD_PRIORITY_NORMAL。

Server和Client都是用CSocket的SetSockOpt函数将收发缓冲区都设置成25K。

问题如下:
1。一个Server对一个Client,Client接收到的数据很多都校验不通过,通过调试在CMySocket(继承CSocket)中的OnReceive中线Sleep(1),再执行Receive接收Server端发来的数据,校验全部通过。这是为什么?
2。一个Server对一个Client,Client启动保存文件线程,Client收了600多组数据后就不收,socket没有死,关闭Server,Client的OnClose相应。是什么原因照成Client不收数据?(保存文件线程使用默认优先级)
3。一个Server对一个Client,Client不启动保存文件线程,Client在收完一组数据校验完后就将数据清除掉(不写入接收数据缓冲区),Server和Client运行稳定。当一个Server对两个Client是,只有一个Client能正常运行,另一个Client只是在收了七八十组数据后就不接收数据了。socket没有死,关闭Server,两个Client的OnClose都有相应。是什么原因造成其中一个Client不收数据了呢?
4。CSocket的SetSockOpt函数设置收发缓冲区对socket有什么影响?延时需要设置吗?应该怎样正确设置?


望高人解答!
...全文
624 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
luckyboy1979 2012-09-07
  • 打赏
  • 举报
回复
这个问题是蛮久之前的了,而且这个接收的程序现在已经不用了,怎么解决的我不记得到。我查看了程序我只能告诉你我解决后是怎么做的,供参考:
我在OnReceive消息函数中调用IOCtl函数,服务端和客户端发送接收的数据是一个固定的结构,代码如下:
OnRecevie(int nErrorCode)
{
DWORD revLen = 0;
IOCtl(FIONREAD,&revLen);
while(revLen<sizeof(MyStruct))
{
IOCtl(FIONREAD,&revLen);
}
//接收一个完整的自己的结构数据并处理数据

CSocket::OnRecevie(nErrorCode);
}
IOCtl(FIONREAD,&revLen)这个函数有的书上说是偷看一下socket接收了多少数据,达到我结构大小说明我可以来处理数据了,接收数据调用recevie函数接收数据的大小也只能是自定义结构的大小,这样收数据应该不会错。
有的说不提倡使用这个方法,我原来这个程序是在局域网使用的,不停地接收数据并用MD5校验没有什么问题。现在我写的在互联网上应用的客户端也是使用这个方法,但是传输的数据量不大,并且都是短连接,也没有什么问题。
你试试看吧!
marrylayking 2012-09-02
  • 打赏
  • 举报
回复
luckyboy1979
你是怎么解决的?我也遇见了这个问题!!!
longren331100 2010-11-25
  • 打赏
  • 举报
回复
up 学习中
jbz001 2010-06-09
  • 打赏
  • 举报
回复
纯属路过·!
luckyboy1979 2010-06-09
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 meng_huali 的回复:]
OnRecieve 结束前 加上:
AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE);
[/Quote]
没有作用

我现在改成client收一个20K的数据后再给Server send一个信息让Server发下一个数据包还是会出现Client接收到的数据很多都校验不通过,通过调试在CMySocket(继承CSocket)中的OnReceive中线Sleep(1),再执行Receive接收Server端发来的数据,校验全部通过的现象。

这个问题怎么解决?
【天运子】 2010-06-09
  • 打赏
  • 举报
回复
OnRecieve 结束前 加上:
AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE);
【天运子】 2010-06-09
  • 打赏
  • 举报
回复
在OnReceive中加
AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE);试试
luckyboy1979 2010-06-09
  • 打赏
  • 举报
回复
我的问题解决了,很感谢king030609 ,是你让我找到了问题所在。
在论坛里看了很多都说CSocket不怎样,我感觉还是蛮好的。
Client端UI线程优先级最终还是没有作调整,是系统默认的普通级别。提升后Server发送的传送结束指令没有收到,不提升能收到。不提升不影响Client端收发速度。
我现在的速度能达到接近7M/秒。Client端收到数据,解包,校验数据一组25个bmp共550K,只要60~80毫秒,没有超过80毫秒的。收到一组数据存文件。已经达到我的要求了。
刚刚跑了半个小时很好,是1个Server对4个Client,数据校验全部没有错误。今天晚上再跑一夜测试,很期待!

还有个问题需要请教的是:
1。CSocket的SetSockOpt函数设置收发缓冲区对socket有什么样的负面影响?这个缓冲区最大能设置成多大?
2。我现在是在局域网内传输数据,在互联网中还适用吗?CSocket的程序能用与互联网的开发吗?比如做成类似升级软件的程序。

希望能有人给出答复。
明天测试OK,结贴给分!!!
klkvc386 2010-06-08
  • 打赏
  • 举报
回复
UP........
luckyboy1979 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 king030609 的回复:]
引用 7 楼 luckyboy1979 的回复:
引用 6 楼 king030609 的回复:
你加了sleep在接收数据分开来了 ,你调试下在OnReceive打个断点,把sleep删除掉,校验应该也正确的。

是不是上次的OnReceive中的接受数据处理数据还没有执行完,下一个OnReceive又来了?

就是这个问题
[/Quote]
如果这个问题一直累积这变得严重了,会造成socket不接受数据了吗?
King030609 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 luckyboy1979 的回复:]
引用 6 楼 king030609 的回复:
你加了sleep在接收数据分开来了 ,你调试下在OnReceive打个断点,把sleep删除掉,校验应该也正确的。

是不是上次的OnReceive中的接受数据处理数据还没有执行完,下一个OnReceive又来了?
[/Quote]
就是这个问题
luckyboy1979 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 king030609 的回复:]
你加了sleep在接收数据分开来了 ,你调试下在OnReceive打个断点,把sleep删除掉,校验应该也正确的。
[/Quote]
是不是上次的OnReceive中的接受数据处理数据还没有执行完,下一个OnReceive又来了?
King030609 2010-06-08
  • 打赏
  • 举报
回复
你加了sleep在接收数据分开来了 ,你调试下在OnReceive打个断点,把sleep删除掉,校验应该也正确的。
luckyboy1979 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 king030609 的回复:]
问题一:多包数据叠在一起,校验时,没有一包包校验,所以校验错误。
[/Quote]
在收数据时每收到20K就解包,在收完一组数据时25个BMP数据都是拆分好的,然后再进行校验的。
我只是在OnReceive中sleep(1)后再执行recevie(接收处理数据),原来拆分数据那部分代码没有该,数据就正确了(校验通过),不解?
lingdu787 2010-06-08
  • 打赏
  • 举报
回复
看不懂呢
luckyboy1979 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 soswaidao 的回复:]
CSocket的SetSockOpt函数设置收发缓冲区对socket有很大影响
[/Quote]
是什么样的影响呢?体现在什么地方?能详细讲讲吗?
King030609 2010-06-08
  • 打赏
  • 举报
回复
问题一:多包数据叠在一起,校验时,没有一包包校验,所以校验错误。
soswaidao 2010-06-08
  • 打赏
  • 举报
回复
CSocket的SetSockOpt函数设置收发缓冲区对socket有很大影响

18,356

社区成员

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

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