void SaveCurIDToFile();
//把当前用户的ID号,加入配置文件中,下次登陆就可以选择了
BOOL SaveUserInfo();
//保存所有用户的信息到磁盘文件中
BOOL LoadFriendInfo();
//从磁盘中读取用户信息
BOOL LoadFaceBmp();
//从磁盘中读取用户头像信息
BOOL LoadLocalAllUserID(CArray<int,int>&aID);
//从配置文件中读出所有可选登陆用户的ID
afx_msg void OnAppAbout();
afx_msg void OnSendBroadcast(); //调用发送广播对话框
afx_msg void OnSendtoAll(); //调用向所有好友发送数据的对话框
afx_msg void OnSysSetup(); //调用服务器设置的对话框
afx_msg void OnSearch(); //调用查找用户的对话框
afx_msg void OnSendFile(); //实现文件的发送(现在还没有完成)
DECLARE_MESSAGE_MAP()
};
§4.13服务器端检查用户是否仍然在线的算法
客户端的用户,可能因为某种异常情况,或死机,或执行非法操作,或忽然掉线,网络发生故障等,可能使客户端程序意外退出。没有或无法发送回下线消息,也有可能发送的下线消息丢失。所以,必须以一定的时间间隔去检查每一个在线的用户,看其是否仍然在线。因为我需要时常发送回当前在线的总人数,所有,可以把发送这条消息作为检查。若发送无响应,则表示用户已经离线了。
算法简述:
以每TimerSpanServer的时间为间隔,向每个在线(或隐身)的用户发送当前有多少人在线的消息,成功就继续。若发送不成功(客户端无响应),就判断此用户不在线上,并从Friends表中查出所有把此人当做朋友的人,向他们发送此人下线的消息(不处理此时发送不成功的情况)。
问题1:为什么不在OnTimer里实现呢?
RE:
开始时,我在OnTimer里实现,但总是不成功,总是判断所有人都不在线上,也就是说发送在线人数的消息不成功。我跟踪程序很长时间后,才发现,在SendData执行完后,CsendSocket的OnReceive才执行,也就是说,在处理这过程里,它好象不允许其它线程运行,换句话说,这个OnTimer函数执行完后,其它线程才获得处理器时间,所以,客户端虽然接受到数据,服务器端却总是说发送失败。而且,在服务器端的菜单响应代码里,也会发生同样的问题。所以我就把这段代码写在一个线程里,可以很好的完成任务,也回避的那种错误。
问题2:为什么响应请求的处理函数中,当发生发送数据失败时,就判断此人不在线,并进行相应处理?那样不是更合理吗?
RE:
开始时,我是这样思考的。但是,在实现时,却遇到一个问题:
在处理中,涉及到很多数据的发送,如果写在里面,那段代码将很长,很乱。更重要的是,在处理某人不在线时,要向其把其当作好友的在线的人发送此人下线的消息,而这些人中,又可能会有发送不成功的人,这样,代码就几乎无法写,是一个深入递归的过程了,这样可能会陷入,既影响了响应用户的时间,也很难实现,所以,我把判断某人是否在线的工作,直接交给这个线程处理。
即使在这个线程里,我也没有对发送下线消息的人是否发送成功,
因为,从循环的角度来考虑,总是会轮到他的,所以我也没有判断,发送某人离线消息的发送是否成功。
§4.14服务器端处理用户请求的算法
算法及描述:
侦听到用户的请求,就会新建一个线程进行处理。根据调用线程的函数传来的参数,根据接受到的数据,取出其类型,根据不同的类型的数据,根据规定的流程进行分类处理用户请求。
此工人线程函数的结构模型为:
UINT ProcessRecvData(LPVOID param)
{
CData* pData=(CData*)param;
UINT index=pData->index;
Switch(index)
{
case ONHIDE::
………………..
break;
case ONLINE:
………………..
break;
………………..
}
}
现在分别对每个处理流程进行分析:
一.case ONLINE: 为用户请求上线的消息,相应处理为:
判断是否为合法用户
若此时,这个人已经在线,就不处理
发送上线成功消息给此用户
如果此用户原状态为隐身,则转到(9)
从数据库中查出此用户的所有好友帐号,并发给此用户
发送所有在线的好友的ID,IP,Port,OnlineState,给此用户
从offbroadcast表中查出所有离线广播,依次发给此用户,并删除在表上相应的数据
从offmsg表中查出所有离线消息,依次发给此用户,并删除在表中相应的数据
查找出把此用户当做朋友的所有用户ID,并向这些用户中在线的或隐身的发送此用户上线消息
二.case ONHIDE: 为用户请求隐身登陆的消息,相应处理流程为:
判断是否为合法用户,否就不处理
若此时,这个人已经在隐身登陆,就不处理
发送隐身登陆成功消息给此用户
如果此用户原状态为在线,则转到(9)
从数据库中查出此用户的所有好友帐号,并发给此用户
发送所有在线的好友的ID,IP,Port,OnlineState,给此用户
从offbroadcast表中查出所有离线广播,依次发给此用户,并删除在表上相应的数据
从offmsg表中查出所有离线消息,依次发给此用户,并删除在表中相应的数据
查找出把此用户当做朋友的所有用户ID,并向这些用户中在线的或隐身的发送此用户隐身登陆消息
三.Case OFFLINE 用户发来的离线消息
判断此用户是否为合法用户,否就不处理
如果此用户已经下线,就不处理
找出把此用户当作好友的人,给其中在线或隐向的发此用户的OFFLINE消息
四.case SEND_MSG_TO_FRIEND: 发给好友的离线消息
case REFUSE_AS_FRIEND: 别人拒绝某人把它加为好友
case ACCEPT_AS_FRIEND: 同意某人加为好友
case FRIEND_IDENTITY_
首页 上一页 11 12 13 14 15 16 17 下一页 尾页 14/17/17
免费vc++网上寻呼QICQ源代码(附带文档)(十四)由毕业论文网(www.huoyuandh.com)会员上传。