基于winsock的局域网通信系统的开发

更新时间:2024-07-10 12:36:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

课程 题目 重 庆 理 工 大 学

课程设计

面向对象程序设计I

基于WinSock的局域

网通信系统的开发

重庆理工大学课程设计

1 系统分析

1.1 模块一

启动登录对话框取消登录意图登入意图申请帐号意图调用基类OnCancel函数关闭窗口用户输入帐号和密码调用基类OnCancel函数关闭窗口,并弹出申请帐号窗口,续模块二构造数据包,像服务器传送登录信息验证成功验证用户名和密码以及数据库回到重新输入用户信息的状态验证失败调用基类OnCancel函数关闭窗口,弹出主对话框窗口并初始化信息,续模块三

这个模块的功能是启动登录对话框,并且在启动后有登入,取消,申请帐号三个可以选择,若要登录则输入正确的帐号和密码即可,这是系统将传密码和帐号去验证是否正确,正确的话就可以登入到主对话框来(模块三),不正确的话会有重新输入的提示.如果选择申请帐号则会弹出申请帐号对话框(模块二).另外还可以点击取消(退出)按钮,则程序将关闭.

2

重庆理工大学课程设计

1.2 模块二

请用户输入注册的信息弹出提示语,光标回到输入昵称处是昵称为空否是密码为空否二次密码为空否弹出提示语,光标回到各自输入处是昵称或密码过长否两密码是否一致是否弹出提示语,光标回到输入第一次密码处是弹出提示语,光标回到二次密码处弹出提示语,光标回到输入密码处关闭注册窗口,弹出注册成功窗口,将新注册的用户信息传送到服务器数据库,并返回一个ID号,此号直接显示在登录窗口,接着用户输入密码进行后续操作.

申请帐号对话框弹出后,用户要输入长度范围内的昵称,以及长度方位内的密码,并且第二次输入的密码要与第一次输入的密码相同,如果不输入点确定也会报错,在确定完输入信息后,点击确定数据库将存放输入的信息,点击取消将回到登录界面.

3

重庆理工大学课程设计

1.3 模块三

初始化对话框界面获取自身消息的数据包并显示,包括好友列表等.更改状态发送消息删除好友查找好友个人设置好友信息退出点击按钮触发改变状态函数是否选中好友弹出提否示语是否选中好友弹出提示语否弹框提示用户选择按哪种方式进行查找是选择要更改的状弹出对话框,态后,发送状态数可以进行聊据包,并且本地状天,并在聊天中获取例如时态记录进行修改间,昵称等消息再弹出一个框,显示查找得到的信息弹出个人信息框,获取个人信息数据包并且可以在框中就行修改个人信息否是否选中好友弹出提示语弹出窗口,提示是否确定退出防止不小心关闭是是构造删除好友数据包并发往服务器是否保存调用关闭窗口函数实现窗口关闭否是弹出窗口,从数据库充获得好友信息数据包,并显示为不可编辑只可查看在本地界面的好友列表,状态列表中删除该好友构造个人信息数据包,返回到服务器的数据库.再次触动确定按钮,不再发送心跳,删除单挑记录,并将这次登录的帐号写入配置文件,关闭窗口结束程序

这个模块中我做的是窗口界面,也就是接口.进入主界面后,可以有更改状态,发送消息,删除好友,查找好友,个人设置,好友消息,退出这几个选项.点击更改状态可以选择自己的状态,一共有三种可供选择,点击查找好友后会弹出一个选择查找方式的窗口,选择方式查到好友后可查看好友资料并加好友,接下来可以与好友聊天,但必须选中好友后再点击发送信息,否则将弹出提示语,这点在点击好友信息按钮和删除好友按钮时也是如此,必须选中后才能操作.另外可以点击个人设置对自己的资料进行填写修改.点击退出会弹出一个确认退出对话框,再次确认后就将退出程序,点取消则返回主对话框.

4

重庆理工大学课程设计

2 系统实现

2.1模块一

CP2PClientApp theApp;

unsigned int CP2PClientApp::_seq_count = 0; //消息号计数器

IM_Config_Parser g_fileobj(\操作配置文件全局对象,配置文件名称imclient.ini

Message_Queue g_rcv_msg_queue;//全局接收消息队列

Message_Queue g_send_msg_queue;//全局发送消息队列

//全局udp通信对象 Udp_Daemon g_udp_daemon; #endif

//从配置文件读取配置信息 if(!g_fileobj.open()) { }

char strValue[MAX_STRING_LEN];

if(g_fileobj.get_string(\

m_ServerInfo.server_ip = ntohl(inet_addr(strValue));//服务器ip AfxMessageBox(\打开配置文件imclient.ini 失败!\return 0;

EN))

5

重庆理工大学课程设计

N))

if(g_fileobj.get_string(\

m_ServerInfo.server_port = atoi(strValue);//服务器端口号

ING_LEN))

if(g_fileobj.get_string(\

m_ClientInfo.recv_producer_num = atoi(strValue);//接收消息线程数

ING_LEN))

if(g_fileobj.get_string(\

m_ClientInfo.send_consumer_num = atoi(strValue);//发送消息线程数

RING_LEN))

if(g_fileobj.get_string(\

m_ClientInfo.process_consumer_num = atoi(strValue);//处理消息线程数

STRING_LEN))

if(g_fileobj.get_string(\

m_ClientInfo.uid = atoi(strValue);//最近登录的用户帐号

m_ClientInfo.client_port = create_client_port(); //获取客户端端口号

void CLoginDlg::OnLogin() {

UpdateData(TRUE);//将界面内容传送给控件成员变量 if(m_nUID < 9999)//用户帐号10000从开始 { }

if(m_strPassword.IsEmpty())//密码不能为空 {

AfxMessageBox(CString(\请输入密码!\

6

AfxMessageBox(CString(\请正确输入用户帐号!\GotoDlgCtrl((CWnd*)GetDlgItem(IDC_UID)); return;

重庆理工大学课程设计

}

}

GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD)); return;

//开始向服务器发送登录信息,然后根据服务器的返回信息 //判断输入的用户名和密码是否正确 IM_Header header;

header.cmd = IM_SESSION_LOGIN; header.id = m_nUID;

header.seq = CP2PClientApp::create_blk_seq(); header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头 char szPassword[MAX_PASSWORD_LEN] = \strcpy(szPassword,m_strPassword.GetBuffer(0)); m_strPassword.ReleaseBuffer();

send_blk->write_buffer(szPassword,MAX_PASSWORD_LEN+1);

send_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列

void CLoginDlg::OnApplyUid() {

CRegisterDlg dlg;//定义注册对话框对象

if(dlg.DoModal() == IDOK)//弹出注册对话框,如果用户在注册对话框中选择{

//向服务器发送注册帐号消息 IM_Header header;

header.cmd = IM_ACCOUNT_REGISTER; header.id = 0;//现在还没有用户号

header.seq = CP2PClientApp::create_blk_seq();

了\确定\按钮

7

重庆理工大学课程设计

}

}

header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头 char szNick[MAX_NICK_LEN+1] = \strcpy(szNick,dlg.m_strNick.GetBuffer(0)); dlg.m_strNick.ReleaseBuffer();

send_blk->write_buffer(szNick,MAX_NICK_LEN+1);// char szPassword[MAX_PASSWORD_LEN+1] = \strcpy(szPassword,dlg.m_strPassword.GetBuffer(0)); dlg.m_strPassword.ReleaseBuffer();

send_blk->write_buffer(szPassword,MAX_PASSWORD_LEN+1);

send_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列

void CLoginDlg::OnCancel() { }

LRESULT CLoginDlg::OnAccountRegister(WPARAM wParam, LPARAM lParam) {

IM_Message_Block* blk = (IM_Message_Block*)lParam;//转化传过来的参数 if(!blk) {

UINT32 uid = 0;

blk->skip(sizeof(IM_Header));//跳过消息头 m_nUID = 0; else

CDialog::OnCancel(); //调用基类的OnCancel函数,关闭对话框,并返回IDCANCEL

8

重庆理工大学课程设计

}

}

blk->read_UINT8(&m_ErrorCode);//读取错误码 blk->read_UINT32(&uid);//读取注册上的id m_nUID = uid;

if(m_ErrorCode==IM_REGISTER_SUCESS && m_nUID!=0) { }

else if(m_ErrorCode==IM_REGISTER_ERROR || m_nUID==0) { }

else if(m_ErrorCode == IM_REGISTER_ERROR_DB) { } delete blk;

AfxMessageBox(CString(\注册帐号失败--数据库错误!\AfxMessageBox(CString(\注册新帐号失败!\CString strTemp;

strTemp.Format(\注册新帐号成功,新帐号为:%u\AfxMessageBox(strTemp);

UpdateData(FALSE);//将成员变量值传给界面

GotoDlgCtrl((CWnd*)GetDlgItem(IDC_UID));//将输入焦点定位到id输入框 return 1;

LRESULT CLoginDlg::OnSessionLogin(WPARAM wParam, LPARAM lParam) {

IM_Message_Block* blk = (IM_Message_Block*)lParam;//转化传过来的参数 if(blk) {

blk->skip(sizeof(IM_Header));//跳过消息头 blk->read_UINT8(&m_ErrorCode);//读取错误码 if(m_ErrorCode == IM_LOGIN_ERROR_PSW) {

AfxMessageBox(CString(\密码错误!\

9

重庆理工大学课程设计

}

}

}

GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD)); return 0;

else if(m_ErrorCode == IM_LOGIN_ERROR_UID_UNVALID) { }

else if(m_ErrorCode == IM_LOGIN_ERROR_DB) { }

else if(m_ErrorCode == IM_LOGIN_SUCCESS) { }

theApp.m_ClientInfo.uid = m_nUID;

OnOK();//如果登录成功则调用基类的OnOK函数关闭对话框,并返AfxMessageBox(CString(\数据库错误,登录失败!\GotoDlgCtrl((CWnd*)GetDlgItem(IDC_UID)); return 0;

AfxMessageBox(CString(\该用户帐号不存在!\GotoDlgCtrl((CWnd*)GetDlgItem(IDC_UID)); return 0;

回IDOK

return 1;

2.2模块二

void CRegisterDlg::OnOK() {

UpdateData(TRUE); //从界面向控件变量传送数据 if(m_strNick.IsEmpty()) //昵称不能为空 {

AfxMessageBox(CString(\请输入昵称!\提醒用户 GotoDlgCtrl((CWnd*)GetDlgItem(IDC_NICK)); //定位输入焦点

10

重庆理工大学课程设计

}

return;

if(m_strPassword.IsEmpty()) { }

if(m_strPasswordAgain.IsEmpty()) { }

if(m_strNick.GetLength() > MAX_NICK_LEN) //昵称不能超长 { }

if(m_strPassword.GetLength() > MAX_PASSWORD_LEN) //密码不能超长 { }

if(m_strPassword != m_strPasswordAgain) {

AfxMessageBox(CString(\两次密码输入不一致!\GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD)); CString strTemp;

strTemp.Format(\密码不能超过%d个字符!\AfxMessageBox(strTemp);

GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD)); return;

CString strTemp;

strTemp.Format(\昵称不能超过%d个字符!\AfxMessageBox(strTemp);

GotoDlgCtrl((CWnd*)GetDlgItem(IDC_NICK)); return;

AfxMessageBox(CString(\请再次输入密码!\

GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD_AGAIN)); return;

AfxMessageBox(CString(\请输入密码!\

GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD)); return;

11

重庆理工大学课程设计

}

}

return;

CDialog::OnOK();//调用基类的OnOk函数,关闭对话框,并返回IDOK

void CRegisterDlg::OnCancel() { }

// TODO: Add extra cleanup here

CDialog::OnCancel();

2.3模块三

void CP2PClientDlg::OnSelchangeOnlineStatus() {

int nCurSel = m_ctrlOnlineStatus.GetCurSel();

if((nCurSel!=theApp.m_ClientInfo.status) || (!m_bIsLogin)) {

//开始发送改变在线状态信息 IM_Header header;

header.cmd = IM_SESSION_STATUS_CHANGE; header.id = theApp.m_ClientInfo.uid;

header.seq = CP2PClientApp::create_blk_seq(); header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头 send_blk->write_UINT32(theApp.m_ClientInfo.uid); send_blk->write_UINT32(theApp.m_ClientInfo.client_ip); send_blk->write_UINT16(theApp.m_ClientInfo.client_port); if(nCurSel == 0) {

send_blk->write_UINT8(IM_STATUS_ONLINE);

12

重庆理工大学课程设计

}

}

}

//本地记录的状态也作相应的改动

theApp.m_ClientInfo.status = IM_STATUS_ONLINE;

else if(nCurSel == 1) { }

else if(nCurSel == 2) { }

else if(nCurSel == 3) { }

send_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列

send_blk->write_UINT8(IM_STATUS_OFFLINE); theApp.m_ClientInfo.status = IM_STATUS_OFFLINE; send_blk->write_UINT8(IM_STATUS_OUTWAY); theApp.m_ClientInfo.status = IM_STATUS_OUTWAY; send_blk->write_UINT8(IM_STATUS_HIDE); theApp.m_ClientInfo.status = IM_STATUS_HIDE;

void CP2PClientDlg::OnSendMsg() {

//查看是否选中了好友,如果选中了则顺便取出跟他的聊天记录 POSITION pos = m_ctrlFriendList.GetFirstSelectedItemPosition(); if(!pos) { }

AfxMessageBox(CString(\请选择好友!\return;

13

重庆理工大学课程设计

int nItem = m_ctrlFriendList.GetNextSelectedItem(pos); //界面上显示的新消息数恢复为 m_ctrlFriendList.SetItemText(nItem,3,\vector* history_msg =

CString strValue = m_ctrlFriendList.GetItemText(nItem,0); unsigned int uid = atoi(strValue.GetBuffer(0)); strValue.ReleaseBuffer();

//查看该好友是否在线,如果在线顺便记住该好友的在线信息 BOOL bIsOnline = FALSE;

usr_info_online* friend_online_info = NULL;

vector::iterator it = m_friend_online_list.begin(); for(; it!=m_friend_online_list.end(); it++) { }

//弹出聊天对话框 CSMsgDlg dlg; m_pChildWnd = &dlg; m_nChatFriendID = uid; //查找该好友的基本信息

vector::iterator it_a = m_friend_list.begin(); for(; it_a!=m_friend_list.end(); it_a++) {

usr_info_base* friend_base_info = (usr_info_base*)*it_a; friend_online_info = (usr_info_online*)*it; if(friend_online_info->user_id == uid) { }

if(friend_online_info->status==IM_STATUS_ONLINE || { }

bIsOnline = TRUE; break;

(vector*)m_ctrlFriendList.GetItemData(nItem);

friend_online_info->status==IM_STATUS_OUTWAY)

14

重庆理工大学课程设计

}

if(friend_base_info->user_id == uid) {

memcpy((char*)&dlg.m_friend_info,(char*)(friend_base_info),sizeof(usr_info_b }

if(bIsOnline)//如果在线则将好友的在线信息拷贝给聊天对话框

memcpy((char*)&dlg.m_friend_online,(char*)(friend_online_info),sizeof(usr_infdlg.m_history_msg = history_msg;//将该好友的历史聊天记录传给聊天对话框 dlg.m_bIsOffline = !bIsOnline;//将该好友是否在线传递给聊天对话框 dlg.DoModal();//显示聊天对话框

m_nChatFriendID = 0;//聊天结束后将记录当前聊天好友id变量重新置

}

break;

ase));

o_online));

void CP2PClientDlg::OnDelFriend() {

POSITION pos = m_ctrlFriendList.GetFirstSelectedItemPosition(); if(!pos) { }

int nItem = m_ctrlFriendList.GetNextSelectedItem(pos); CString strValue = m_ctrlFriendList.GetItemText(nItem,0); unsigned int uid = atoi(strValue.GetBuffer(0)); strValue.ReleaseBuffer(); //开始发送删除好友数据包 IM_Header header;

header.cmd = IM_CONTACT_DEL; header.id = theApp.m_ClientInfo.uid;

AfxMessageBox(CString(\请选择好友!\return;

15

重庆理工大学课程设计

}

header.seq = CP2PClientApp::create_blk_seq(); header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头 send_blk->write_UINT32(uid);

send_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列

void CP2PClientDlg::OnFindContact() { }

void CP2PClientDlg::OnPersonalSet() {

CContactInfoDlg dlg;//定义联系人信息对话框类对象 dlg.m_nOpenMode = 1;//对话框打开模式为修改信息

//将当前用户的详细信息传给联系人信息对话框中相应的成员变量 dlg.m_nUID = m_myself_info.user_id; dlg.m_strNick = CString(m_myself_info.nick);

CSetSearchTypeDlg set_type_dlg;//定义设置查找类型对话框类对象 if(set_type_dlg.DoModal() == IDOK)//弹出对话框,如果点击了\确定\按钮 { }

CQueryContactResultDlg result_dlg;//定义查找联系人结果对话框类对象 result_dlg.m_nUID = set_type_dlg.m_nUID;//传递查找类型信息 result_dlg.m_strNick = set_type_dlg.m_strNick;

result_dlg.m_nSearchType = set_type_dlg.m_nSearchType;

m_pChildWnd = &result_dlg;//记录当前子对话框,便于后面转发消息 result_dlg.DoModal();//显示查找联系人结果对话框

16

重庆理工大学课程设计

}

dlg.m_strName = CString(m_myself_info.name); dlg.m_strEmail = CString(m_myself_info.email); dlg.m_strTelephone = CString(m_myself_info.telephone); dlg.m_strProfession = CString(m_myself_info.profession); dlg.m_strCollege = CString(m_myself_info.college); dlg.m_strNote = CString(m_myself_info.note); dlg.m_nGender = m_myself_info.gengder; dlg.m_nAge = m_myself_info.age; dlg.m_nPic = m_myself_info.picture;

m_pChildWnd = &dlg;//记录弹出的子窗口句柄,方便转发消息 dlg.DoModal();//弹出对话框

void CP2PClientDlg::OnCancel() { }

void CP2PClientDlg::InitialInterface()//初始化界面 {

//初始化界面

m_ctrlFriendList.SetExtendedStyle (LVS_EX_FULLROWSELECT);//设置整行m_ctrlFriendList.InsertColumn(0,\用户帐号\m_ctrlFriendList.InsertColumn(1,\昵称\m_ctrlFriendList.InsertColumn(2,\状态\m_ctrlFriendList.InsertColumn(3,\新消息数\m_ctrlOnlineStatus.AddString(\上线\m_ctrlOnlineStatus.AddString(\隐身\

CDialoge D_dlg; //定义一个Dialoge类对象,用于防止意外关闭 if(D_dlg.DoModal()==IDOK) { }

Quit();

CDialog::OnCancel();

选中模式

17

重庆理工大学课程设计

}

m_ctrlOnlineStatus.AddString(\离开\m_ctrlOnlineStatus.SetCurSel(0);

void CP2PClientDlg::GetFriendList() { }

void CP2PClientDlg::GetMySelfInfo() {

//发送获取自己信息的消息包 IM_Header header;

header.cmd = IM_CONTACT_SEARCH; header.id = theApp.m_ClientInfo.uid;

header.seq = CP2PClientApp::create_blk_seq(); header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头 send_blk->write_UINT8(IM_SEARCH_ID); send_blk->write_UINT32(theApp.m_ClientInfo.uid); send_blk->write_UINT16(0);//只取一次

send_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 //发送获取好友列表消息 IM_Header header;

header.cmd = IM_CONTACT_GET_LIST; header.id = theApp.m_ClientInfo.uid;

header.seq = CP2PClientApp::create_blk_seq(); header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头

send_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列

18

重庆理工大学课程设计

}

send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列

void CP2PClientDlg::GetFriendOnlineInfo() { }

void CP2PClientDlg::Quit()//退出程序 {

KillTimer(HEARTBEAT_TIMER); //取消心跳包定时器消息 //开始发送退出信息 IM_Header header;

header.cmd = IM_SESSION_LOGOUT; header.id = theApp.m_ClientInfo.uid; //发送获取好友在线信息消息

vector::iterator it_a = m_friend_list.begin(); for(; it_a!=m_friend_list.end(); it_a++) { }

usr_info_base* temp = (usr_info_base*)*it_a; //开始发送改变在线状态信息 IM_Header header;

header.cmd = IM_GET_ONLINE_INFO; header.id = theApp.m_ClientInfo.uid;

header.seq = CP2PClientApp::create_blk_seq(); header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头 send_blk->write_UINT32(temp->user_id);

send_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列

19

重庆理工大学课程设计

}

header.seq = CP2PClientApp::create_blk_seq(); header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头

send_blk->write_buffer(theApp.m_ClientInfo.password,MAX_PASSWORD_LEsend_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列 //将最近登录帐号重新写入配置文件 char szTemp[MAX_STRING_LEN] = \

g_fileobj.update_string(\//删除和所有好友的聊天记录

int nRows = m_ctrlFriendList.GetItemCount(); for(int i=0; i

vector* data =

vector::iterator it = data->begin(); for(; it!=data->end(); it++) { }

delete data;//删除记录在ListCtrl上的指针

CString* msg = (CString*)*it; delete msg;//删除单条聊天记录

N+1);

d,szTemp,10));

(vector*)m_ctrlFriendList.GetItemData(i);

void CP2PClientDlg::OnClose() {

CDialoge D_dlg;

//定义一个Dialoge类对象,用于防止意外关闭

20

重庆理工大学课程设计

}

if(D_dlg.DoModal()==IDOK) { }

Quit();

CDialog::OnCancel();

LRESULT CP2PClientDlg::OnSessionHeartbeat(WPARAM wParam, LPARAM lParam) {

IM_Message_Block* blk = (IM_Message_Block*)lParam; if(blk) {

unsigned int nTotalOnlineNum = 0; blk->set_cursor(sizeof(IM_Header)); blk->skip(sizeof(unsigned int));

blk->read_UINT32(&theApp.m_ClientInfo.client_ip); blk->read_UINT16(&theApp.m_ClientInfo.client_port); blk->read_UINT8(&theApp.m_ClientInfo.status); blk->read_UINT32(&nTotalOnlineNum); //如果在线人数有变化,则在即时消息框中显示 if(m_nTotalOnlineNum != nTotalOnlineNum) {

m_nTotalOnlineNum = nTotalOnlineNum; CString strMsg;

char szTemp[MAX_STRING_LEN] = \m_ctrlMsgList.GetWindowText(strMsg); strMsg = strMsg + \当前在线用户总数为:\m_ctrlMsgList.SetWindowText(strMsg); //让编辑框中的滚动条滚动到最底端 POINT pt; //取得滚动范围

CString(itoa(m_nTotalOnlineNum,szTemp,10)) + \

21

重庆理工大学课程设计

}

}

}

m_ctrlMsgList.GetScrollRange(SB_VERT, (LPINT)&pt.x, pt.x = 0;

m_ctrlMsgList.SendMessage(EM_LINESCROLL, pt.x, pt.y);

(LPINT)&pt.y);

delete blk;

//收到第一条心跳信息的回复后才发送上线信息,因为发送上线 //信息的时候需要用到自己的ip,端口等信息 if(!m_bIsLogin) { }

OnSelchangeOnlineStatus(); m_bIsLogin = TRUE;

return 1;

LRESULT CP2PClientDlg::OnContactAdd(WPARAM wParam, LPARAM lParam) {

usr_info_base* uib = (usr_info_base*)wParam;//取出好友详细信息 IM_Message_Block* blk = (IM_Message_Block*)lParam; if(!uib || !blk)

return 0;

blk->set_cursor(sizeof(IM_Header)); unsigned int uid = 0; blk->read_UINT32(&uid);

blk->skip(sizeof(unsigned char));//跳过子命令 unsigned char error_code = 0; blk->read_UINT8(&error_code);

if(error_code == IM_CONTACT_ADD_SUCCESS) {

//添加好友成功,开始添加到界面上 char szTemp[MAX_STRING_LEN] = \int nRows = m_ctrlFriendList.GetItemCount();

22

重庆理工大学课程设计

}

m_ctrlFriendList.InsertItem(nRows,itoa(uib->user_id,szTemp,10)); //用于存储将要在该好友身上发生的聊天记录 vector* data = new vector; m_ctrlFriendList.SetItemData(nRows,(DWORD)data); m_ctrlFriendList.SetItemText(nRows,1,(char*)uib->nick); m_ctrlFriendList.SetItemText(nRows,2,\离线\

m_ctrlFriendList.SetItemText(nRows,3,\现在还没有新消息 CString strTemp;

strTemp.Format(\添加好友%u[%s]成功!\AfxMessageBox(strTemp); m_friend_list.push_back(uib);

else if(error_code == IM_CONTACT_ADD_ERROR) { }

//发送获取该好友在线信息消息 IM_Header header;

header.cmd = IM_GET_ONLINE_INFO; header.id = theApp.m_ClientInfo.uid;

header.seq = CP2PClientApp::create_blk_seq(); header.reserved = 0; //开始构造数据包

IM_Message_Block* send_blk = new IM_Message_Block; send_blk->write_header(header);//构造消息头 send_blk->write_UINT32(uid);

send_blk->src_ip_ = theApp.m_ServerInfo.server_ip;//填充该消息的目的地 send_blk->src_port_ = theApp.m_ServerInfo.server_port; send_blk->length_ = send_blk->get_cursor();//填充消息长度 g_send_msg_queue.push_msg(send_blk);//将消息放入发送消息队列

CString strTemp;

strTemp.Format(\添加好友%u[%s]失败!\AfxMessageBox(strTemp); delete uib; return 0;

23

重庆理工大学课程设计

}

delete blk; return 1;

LRESULT CP2PClientDlg::OnContactAddN(WPARAM wParam, LPARAM lParam) { }

LRESULT CP2PClientDlg::OnContactDel(WPARAM wParam, LPARAM lParam) {

IM_Message_Block* blk = (IM_Message_Block*)lParam; if(!blk)

return 0;

//先读取出删除的好友的uid和错误号 blk->set_cursor(sizeof(IM_Header)); unsigned int uid = 0; unsigned char error_code = 0;

IM_Message_Block* blk = (IM_Message_Block*)lParam; if(!blk)

return 0;

blk->set_cursor(sizeof(IM_Header)); unsigned int uid = 0; blk->read_UINT32(&uid); CString strMsg;

char szTemp[MAX_STRING_LEN] = \m_ctrlMsgList.GetWindowText(strMsg);

strMsg = strMsg + CString(itoa(uid,szTemp,10)) + \加你为好友了!\\r\\n\m_ctrlMsgList.SetWindowText(strMsg); //让编辑框中的滚动条滚动到最底端 POINT pt; //取得滚动范围

m_ctrlMsgList.GetScrollRange(SB_VERT, (LPINT)&pt.x, (LPINT)&pt.y); pt.x = 0;

m_ctrlMsgList.SendMessage(EM_LINESCROLL, pt.x, pt.y); delete blk; return 1;

24

重庆理工大学课程设计

blk->read_UINT32(&uid); blk->read_UINT8(&error_code); CString strTemp;

if(error_code == IM_CONTACT_DEL_SUCCESS) {

//从好友列表中删除

vector::iterator it_f = m_friend_list.begin(); for(; it_f!=m_friend_list.end();) { }

//从在线好友列表中删除

vector::iterator it_o = m_friend_online_list.begin(); for(; it_o!=m_friend_online_list.end();) { }

//从界面上删除

int nRows = m_ctrlFriendList.GetItemCount(); CString strValue; for(int i=0; i

strValue = m_ctrlFriendList.GetItemText(i,0); if(uid == atoi(strValue.GetBuffer(0))) {

//删除跟他的聊天记录

usr_info_online* temp = (usr_info_online*)*it_o; if(temp->user_id == uid)

it_o = m_friend_online_list.erase(it_o); it_o++; else

usr_info_base* temp = (usr_info_base*)*it_f; if(temp->user_id == uid)

it_f = m_friend_list.erase(it_f); it_f++; else

25

重庆理工大学课程设计

}

CContactInfoDlg dlg;//定义联系人信息对话框类对象 dlg.m_nOpenMode = 0;//对话框打开模式为查看信息

//将当前用户的详细信息传给联系人信息对话框中相应的成员变量 dlg.m_nUID = m_myself_info.user_id; dlg.m_strNick = CString(m_myself_info.nick); dlg.m_strName = CString(m_myself_info.name); dlg.m_strEmail = CString(m_myself_info.email); dlg.m_strTelephone = CString(m_myself_info.telephone); dlg.m_strProfession = CString(m_myself_info.profession); dlg.m_strCollege = CString(m_myself_info.college); dlg.m_strNote = CString(m_myself_info.note); dlg.m_nGender = m_myself_info.gengder; dlg.m_nAge = m_myself_info.age; dlg.m_nPic = m_myself_info.picture; dlg.DoModal();//显示联系人信息对话框

31

重庆理工大学课程设计

3 系统测试

3.1 如何设计测试数据

通过申请一个帐号来验证是否可以实现申请功能,过程中要故意将密码长度输入不一致或者出错,看是否会出现提示,申请成功后测试是否能正确登录,并且测试在输错帐号和输错密码时会出现什么.若能正常登录,则逐一测试主对话框界面的窗口功能是否能实现.

3.2 系统测试

3.2.1 模块一

(1) 测试数据1:帐号100000密码1

测试结果:点击登录能进入主界面,点击申请能进入注册界面 测试结果分析:该登录对话框的功能能实现 (2) 测试数据2:无

32

重庆理工大学课程设计

测试结果:能进入主界面对话框 测试结果分析:该功能可以实现

3.2.2 模块二

(1)测试数据1:无

测试结果:能弹出用户注册对话框

测试结果分析:该对话框弹出功能完备

(2)测试数据2:新帐号昵称aaa,第一密码123,第二密码1,再改第二 密码为123

测试结果:刚密码不一致时会弹出提示,再次输入正确密码后弹出注 册成功,并返回一个帐号. 测试结果分析:能实现注册新帐号的功能

33

重庆理工大学课程设计

3.2.3 模块三(因为做窗口的原因,测试数据结果和分析写一起)

(1)测试图1:登录主界面,此时登录另一个帐号,实时消息中能显示.

(2)测试图2:点击查找好友,弹出设定查找类型,三种都能查找成功.

34

重庆理工大学课程设计

(3)测试图3:要与好友聊天或者查看好友信息或者要删除好友都要先 选中好友才能操作.

(4)点击发送信息,弹出如此图示的聊天对话框.

35

重庆理工大学课程设计

(5)点击删除好友后,弹出提示删除成功的对话框.

(6)点击个人设置,弹出自己的信息窗口,可以进行修改.

总的分析:主对话框的功能基本都能实现,除了查看好友信息出了点 问题,其他都能正常运行,功能都能得到实现.

36

重庆理工大学课程设计

4 总结

4.1系统工作总结

在登录窗口和注册窗口这两个窗口的工作量比较小,也相对比较独立,但是作为用户与服务器间的接口,在功能完备的情况下还要尽量保持美观.在这次我做的窗口中,因为能力所限,没有做的很美观,仅仅做到可以使用.在登录窗口弹出前,客户端会先配置文件,然后连接服务器,可以连接后才能进行后续的操作.注册窗口在完成后会将数据返回到DB中,接着注册窗口能自动关闭并回到登录窗口.在主对话框我做的不是核心工作,而是界面工作,在界面与代码的连接过程中虽然出了点麻烦,但在大家的努力下还是实现了功能.

4.2 心得体会

这是我第一次做MFC方面的工作,在一开始的困惑之余,还感觉这是挺有趣的一件工作.以前以为只能用黑框框来运行程序,现在更像QQ那样弹出小窗口,然后看着自己的程序通过这些一个个窗口运行起来就觉得很有成就感.当然现在我能做的也不多,并且没有达到熟练的地步,以后得多多使用才不会生疏.从整体来说,这是个很大的工程,并且在分工上很多方面都会有交集,从组长那我也学到了不少知识.我认为不足之处是我没有做数据库那部分,这样那些没做的部分的知识就不明白了.当然,我对我们组所完成的工作感到开心.

37

本文来源:https://www.bwwdw.com/article/92t.html

Top