LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

飞鸽传书源代码

admin
2016年12月23日 18:37 本文热度 6043
本文分析了飞鸽传输核心传送过程。
  1. DWORD WINAPI TMainWin::SendFileThread(void *_sendFileObj)
  2. {
  3. SendFileObj *obj = (SendFileObj *)_sendFileObj;
  4. fd_set fds;
  5. fd_set *rfds = NULL, *wfds = &fds;
  6. timeval tv;
  7. int sock_ret;
  8. BOOL ret = FALSE, completeWait = FALSE;
  9. // 这里SendFileFunc根据command类型自动选择两种函数 : send file or send directory
  10. BOOL (TMainWin::*SendFileFunc)(SendFileObj *obj) =
  11. obj->command == IPMSG_GETDIRFILES ? TMainWin::SendDirFile : TMainWin::SendFile;
  12. FD_ZERO(&fds);
  13. FD_SET(obj->conInfo->sd, &fds);
  14. // 这里for条件引入了一个简单的超时机制
  15. // 正常情况下,只要文件未传送完,循环不会退出
  16. for (int waitCnt=0; waitCnt < 180 && obj->hThread != NULL; waitCnt++)
  17. {
  18. tv.tv_sec = 1, tv.tv_usec = 0;
  19. // 这里select有什么用途呢? 对于select功能我还不是完全明白
  20. // 根据我的分析,这里主要是利用了select函数的等待功能
  21. // 如果sd描述符没有就绪,则在select中最久等待1秒
  22. // 如此反复等待最多180次,也就是3分钟,超过三分钟后,for循环结束
  23. if ((sock_ret = ::select(obj->conInfo->sd + 1, rfds, wfds, NULL, &tv)) > 0)
  24. {
  25. // 套接字可用,清除等待
  26. waitCnt = 0;
  27. //下面的代码是一个有限状态机
  28. if (completeWait)
  29. {
  30. // 本分支在文件发送完后执行
  31. if (::recv(obj->conInfo->sd, (char *)&ret, sizeof(ret), 0) >= 0)
  32. ret = TRUE;
  33. break;
  34. }
  35. else if ((mainWin->*SendFileFunc)(obj) != TRUE)
  36. {
  37. //本分支仅在发送出错时进行
  38. break;
  39. }
  40. else if (obj->status == FS_COMPLETE)
  41. {
  42. // 本分支在发送完成后执行
  43. completeWait = TRUE, rfds = &fds, wfds = NULL;
  44. if (obj->fileSize == 0) { ret = TRUE; break; }
  45. }
  46. }
  47. else if (sock_ret == 0) {
  48. // select超时,重置fds
  49. FD_ZERO(&fds);
  50. FD_SET(obj->conInfo->sd, &fds);
  51. }
  52. else if (sock_ret == SOCKET_ERROR) {
  53. // select错误,算了,离去吧~
  54. break;
  55. }
  56. }
  57. // 如果发送的是文件夹,还需要擦一下屁股
  58. if (obj->isDir)
  59. {
  60. mainWin->CloseSendFile(obj);
  61. while (--obj->dirCnt >= 0)
  62. ::FindClose(obj->hDir[obj->dirCnt]);
  63. }
  64. // ret是对方发回的返回值,告知发送方是否完成接收
  65. obj->status = ret ? FS_COMPLETE : FS_ERROR;
  66. // 发送TCPEVENT消息,关闭句柄
  67. // 消息处理流程: EventUser->TcpEvent->EndSendFile
  68. mainWin->PostMessage(WM_TCPEVENT, obj->conInfo->sd, FD_CLOSE);
  69. // 退出发送线程
  70. ::ExitThread(0);
  71. return 0;
  72. }

上面传送数据最重要的一句是:

else if ((mainWin->*SendFileFunc)(obj) != TRUE)

SendFileFunc的实际内容是什么呢?由函数开始赋值的指针知道:

  1. BOOL TMainWin::SendFile(SendFileObj *obj)
  2. {
  3. if (obj == NULL || obj->hFile == INVALID_HANDLE_VALUE) //判断文件句柄是否合法
  4. return FALSE;
  5. int size = 0;
  6. _int64 remain = obj->fileSize - obj->offset; //取得还需要传递的总字节数
  7. //传数据
  8. if (remain > 0 && (size = ::send(obj->conInfo->sd, obj->mapAddr + (obj->offset % cfg->ViewMax), remain > cfg->TransMax ? cfg->TransMax : (int)remain, 0)) < 0)
  9. return FALSE;
  10. // 根据本次成功发送的数据量,调整offset
  11. obj->offset += size;
  12. // 如果offset等于文件大小了,那么设置obj状态为完成
  13. // 由于存在传文件夹模式和传文件模式,所以状态分情况设置
  14. if (obj->offset == obj->fileSize)
  15. obj->status = obj->command == IPMSG_GETDIRFILES ? FS_ENDFILE : FS_COMPLETE;
  16. else if ((obj->offset % cfg->ViewMax) == 0)//没有完成,但是已经传送完成了本部分数据映射,需要调整映射窗口
  17. {
  18. ::UnmapViewOfFile(obj->mapAddr); // 删除旧映射
  19. remain = obj->fileSize - obj->offset; // 计算新的剩余量
  20. // 映射下一块,一次8M ,如果只剩下最后一点了,则少于8M (remain)
  21. obj->mapAddr = (char *)::MapViewOfFile(obj->hMap, FILE_MAP_READ, (int)(obj->offset >> 32), (int)obj->offset, (int)(remain > cfg->ViewMax ? cfg->ViewMax : remain));
  22. }
  23. // 更新总消耗时间
  24. obj->conInfo->lastTick = ::GetTickCount();
  25. return TRUE;
  26. }

很多朋友向我要飞鸽带注释的源码,实在很抱歉,我只注释了这么多,其余的也没有深入地看。如果你对带注释的源码感兴趣,不妨来这里看看:http://code.google.com/p/ipigeon/这是我在GoogleCode上开的一个项目,大家一起来注释飞鸽源码吧!

该文章在 2016/12/23 18:37:41 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved