IPMSG(飞秋)源代码调试笔记
1、怎么发送普通消息?
进行socket异步select选择,每个消息都是一个Msg包,并且分配一个senddlg为其发送消息。消息协议可以参考其他文档,消息统一封装成文本的方式发送,封装方式为[属性1:属性2:...:消息扩展消息],属性和属性之间和消息之间用冒号隔开,消息和扩展消息用消息结构体的exOffset标记隔开,发送的内容可以协定解密方式。
2、使用udp协议发送,如何确定消息是否已经发送成功?
消息发送出去,对方收到消息后会返回一条消息接收成功的确认消息,
然后发送端为每个senddlg开启一个ontimer函数,每1500ms确定一次(时间可以自己配置)发送出去的消息是否收到的回应,如果未收到则重新发送。
3、接收端如何确定两个消息是一样的,而丢弃后面的?
判断packetNo,判断addr ,判断 portNo,pocketNo是根据time()生成的。
4、msg 结构体(如下)的exOffset字段干啥用的?
struct MsgBuf {HostSub hostSub;int version;int portNo;ULONG packetNo;ULONG command;int exOffset; // expand message offset in msgBufint dummy;char msgBuf[MAX_UDPBUF];void Init(MsgBuf *org) {if (org == NULL) {memset(this, 0, (char *)&this->dummy - (char *)this);*msgBuf = 0;return;}memcpy(this, org, (char *)&this->dummy - (char *)this);strcpy(this->msgBuf, org->msgBuf);strcpy(this->msgBuf + exOffset, org->msgBuf + exOffset);}
};
exOffset表示可以发送除消息意外的其他内容(比如组名称啥的,和消息区别开来),但前提是整个消息(加上exOffset)大小要小于MAX_UDPBUF。其实不用这个字段也行,我们可以把组名称啥的封装到消息buf里面去
5、如果输入的字符串超出了MAX_UDPBUF怎么办?
飞秋里面没处理,直接截断。。。
可以查看如下两处处理方式:
(1)从编辑框获取文本的时候,最大长度就用MAX_UDPBUF:
GetDlgItemText(SEND_EDIT, msg.msgBuf, MAX_UDPBUF);
(2)收取消息的时候,还会进行如下代码判断:
if (exStr && (ex_len = strlen(exStr) + 1) < MAX_UDPBUF -1)
{
if (++msg->exOffset + ex_len >= MAX_UDPBUF)
msg->msgBuf[(msg->exOffset = MAX_UDPBUF - ex_len) -1] = '\0';//这句表示超出直接截断
memcpy(msg->msgBuf + msg->exOffset, exStr, ex_len);
}
6、在创建IPM的时候就进入了tcp_socket 就进入了listen的状态。然后udp和tcp还可以同时使用一个端口,包括登入退出发送的广播消息一并使用同一个端口,UDP发送消息,TCP发送文件,对socket的异步管理比较到位。
7、文件发送如何高效?
(1)使用内存映射文件的方式打开文件,内存映射文件方式能高效处理大文件。
(2)为发送和接收程序单独开线程,并使用select选择模型处理数据。
用内存映射方式打开关闭文件:
BOOL TMainWin::OpenSendFile(const char *fname, SendFileObj *obj)
{DWORD lowSize, highSize, viewSize;if ((obj->hFile = ::CreateFile(fname, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE){lowSize = ::GetFileSize(obj->hFile, &highSize);if ((obj->fileSize = (_int64)highSize << 32 | lowSize) == 0)return TRUE;obj->hMap = ::CreateFileMapping(obj->hFile, 0, PAGE_READONLY, highSize, lowSize, 0);viewSize = (int)(obj->fileSize > cfg->ViewMax ? cfg->ViewMax : obj->fileSize);highSize = (int)(obj->offset >> 32);lowSize = (int)((obj->offset / cfg->ViewMax) * cfg->ViewMax);obj->mapAddr = (char *)::MapViewOfFile(obj->hMap, FILE_MAP_READ, highSize, lowSize, viewSize);if (obj->mapAddr && IsBadReadPtr(obj->mapAddr, 1)){CloseSendFile(obj);return FALSE;}}return obj->mapAddr ? TRUE : FALSE;
}BOOL TMainWin::CloseSendFile(SendFileObj *obj)
{if (obj == NULL)return FALSE;::UnmapViewOfFile(obj->mapAddr);obj->mapAddr= NULL;::CloseHandle(obj->hMap); obj->hMap = NULL;::CloseHandle(obj->hFile); obj->hFile = INVALID_HANDLE_VALUE;obj->offset = 0;return TRUE;
}
发送文件线程:
DWORD WINAPI TMainWin::SendFileThread(void *_sendFileObj)
{SendFileObj *obj = (SendFileObj *)_sendFileObj;fd_set fds;fd_set *rfds = NULL, *wfds = &fds;timeval tv;int sock_ret;BOOL ret = FALSE, completeWait = FALSE;BOOL (TMainWin::*SendFileFunc)(SendFileObj *obj) =obj->command == IPMSG_GETDIRFILES ? &TMainWin::SendDirFile : &TMainWin::SendFile;FD_ZERO(&fds);FD_SET(obj->conInfo->sd, &fds);for (int waitCnt=0; waitCnt < 180 && obj->hThread != NULL; waitCnt++){tv.tv_sec = 1, tv.tv_usec = 0;if ((sock_ret = ::select(obj->conInfo->sd + 1, rfds, wfds, NULL, &tv)) > 0){waitCnt = 0;if (completeWait){ // dummy read if (::recv(obj->conInfo->sd, (char *)&ret, sizeof(ret), 0) >= 0)ret = TRUE;break;}else if ((mainWin->*SendFileFunc)(obj) != TRUE)break;else if (obj->status == FS_COMPLETE){completeWait = TRUE, rfds = &fds, wfds = NULL;if (obj->fileSize == 0) { ret = TRUE; break; }}}else if (sock_ret == 0) {FD_ZERO(&fds);FD_SET(obj->conInfo->sd, &fds);}else if (sock_ret == SOCKET_ERROR) {break;}}if (obj->isDir){mainWin->CloseSendFile(obj);while (--obj->dirCnt >= 0)::FindClose(obj->hDir[obj->dirCnt]);}obj->status = ret ? FS_COMPLETE : FS_ERROR;mainWin->PostMessage(WM_TCPEVENT, obj->conInfo->sd, FD_CLOSE);::ExitThread(0);return 0;
}BOOL TMainWin::SendFile(SendFileObj *obj)
{if (obj == NULL || obj->hFile == INVALID_HANDLE_VALUE)return FALSE;int size = 0;_int64 remain = obj->fileSize - obj->offset;int transMax = cfg->TransMax - (int)(obj->offset % cfg->TransMax);if (remain > 0 && (size = ::send(obj->conInfo->sd, obj->mapAddr + (obj->offset % cfg->ViewMax), (int)(remain > transMax ? transMax : remain), 0)) < 0)return FALSE;obj->offset += size;if (obj->offset == obj->fileSize)obj->status = obj->command == IPMSG_GETDIRFILES ? FS_ENDFILE : FS_COMPLETE;else if ((obj->offset % cfg->ViewMax) == 0) //
{::UnmapViewOfFile(obj->mapAddr);remain = obj->fileSize - obj->offset;obj->mapAddr = (char *)::MapViewOfFile(obj->hMap, FILE_MAP_READ, (int)(obj->offset >> 32), (int)obj->offset, (int)(remain > cfg->ViewMax ? cfg->ViewMax : remain));}obj->conInfo->lastTick = ::GetTickCount();return TRUE;
}BOOL TMainWin::EndSendFile(SendFileObj *obj)
{if (obj == NULL)return FALSE;if (obj->hThread){HANDLE hThread = obj->hThread;obj->hThread = 0;
::WaitForSingleObject(hThread, INFINITE);::CloseHandle(hThread);}if (::closesocket(obj->conInfo->sd) != 0)obj->status = FS_ERROR; CloseSendFile(obj);if (obj->isDir)free(obj->hDir);shareMng->EndHostShare(obj->packetNo, &obj->host->hostSub, obj->fileInfo, obj->status == FS_COMPLETE ? TRUE : FALSE);sendFileList.DelObj(obj);delete obj->conInfo;delete obj;return TRUE;
}
IPMSG(飞秋)源代码调试笔记相关推荐
- java飞秋源码,feiQiu 实现飞秋系统,和qq 类似,能够 客户端和服务器端 Java Develop 259万源代码下载- www.pudn.com...
文件名称: feiQiu下载 收藏√ [ 5 4 3 2 1 ] 开发工具: Java 文件大小: 19833 KB 上传时间: 2016-06-13 下载次数: 0 提 供 者: 王小青 ...
- OMAPL138调试笔记
title: Linux 嵌入式使用 tags: 新建,模板,小书匠 grammar_cjkRuby: true Copyright (C) @2018 Widic Filename:File-fun ...
- 这说明什么?【转载】早点长大的飞秋2013
[转载]早点长大的飞秋 作者: i_like_cpp - 日期:2013-05-07 浏览 0 次 今天的早点长大的飞秋,早点长大,为了早点成为神奇的土地 ...
- 进行api的HTML5inlinehook操作(飞秋官方下载)
进行api的HTML5inlinehook操作.hook的api主要有findnextfilea findnextfilew enumservicesstatusa enumservicesstatu ...
- 那信息闭塞的地方 飞秋官方下载
不要惊奇这种观点,在hongjin2们那信息闭塞的地方 飞秋官方下载,当时有谁能想到程序设计技术会有如此大的改变社会的能力?飞秋官方下载之所以不懈学习,纯粹是为了解脱精神上的困惑,在技术的海洋中忘却生 ...
- 刚刚看到网友的签名 飞秋官网下载
刚刚看到网友的签名 飞秋官网下载,不怕狼一样的敌人,就怕狗一样的朋友,现在很有同感,我处处谦让你们,我换来的就是你们的小人之腹,我从来不在老板面前说你们的工作出现什么问题,从来不当着老板的面说你们的不 ...
- 企业巧妙运用飞秋提高工作效率
飞秋2010(FeiQ)是一款局域网即时通讯.传送文件的绿色免费软件,它参考了飞鸽传书(IPMSG)和QQ, 完全兼容飞鸽传书(IPMSG)协议,具有局域网传送方便,速度快,操作简单.不需要服务器支持 ...
- 需要符合互联网时代需求的《飞秋》
飞秋管理员工即时通讯帐号,另外,企业可以通过IPMSG来注册自己专属的沟通平台,为每个员工分配飞秋后缀的员工帐号,这种集中式的管理,不仅便于企业管理者管理,而且也能提升企业形象.当新员工入职时,管理人 ...
- 封网后聊天就用“飞秋”
想在局域网内部聊天,有没有好的软件呢,最好不需要安装服务器,只要安装一个小软件就行了,界面还要像QQ,支持动态表情的,可以眉目传情啊,以前有个"飞鸽"可以实现互通信息与文件,但是界 ...
最新文章
- 【深度学习】(5) 简单网络,案例:服装图片分类,附python完整代码
- nginx下后端realserver健康检测模块ngx_http_upstream_check_module
- 将本地SHH文件导入SourceTree配置
- Arduino IDE 如何添加 ESP32 开发板?
- 史上最详细的XGBoost实战
- ws配置 zuul_SpringCloud系列研究---服务网关zuul
- linux下如何为redis配置path,linux环境下如何启动redis
- [BZOJ3297][USACO2011 Open]forgot
- 计算机毕业设计JAVA企业员工业绩考核系统mybatis+源码+调试部署+系统+数据库+lw
- 如何使用计算机管理员账户密码是什么意思,电脑管理员密码是什么
- 关于diskpart的命令问题记录
- policy服务器未能登录,win7电脑提示group policy client服务未能登录的解决方法
- Week 7 Homework
- 安卓 11 文件储存
- 微信小程序中实现地图导航
- SWFUpload 使用说明
- 解决SVN pristine text xxxx not present问题
- 关于DBC文件的创建
- ipad还能横行霸道多久
- 网络规划设计师水平考试备考资料(9.网络分析与设计案例)
热门文章
- Facebook、YouTube都会遇到的内容审核难题,今日头条是怎么解决的?
- 直播期间主播强制关闭软件的处理办法
- JAVA程序员装机必备软件攻略
- 能不能不经妻子同意,就把和妻子共有的房子抵押给银行用来贷款 ?
- PR软件中的音频硬件扬声器显示不工作的故障
- [附源码]java毕业设计医院药房管理系统
- dede模板php代码,织梦dede模板内怎样到场php代码_CMS体系建站教程
- Oauth2.0介绍
- FOC电动车控制器代码 原理图 pcb 无刷电机FOC控制量产方案,原理图,PCB,源代码
- Unity3D vuforia SDK 预制物体各组件功能说明