基于winsock的局域网通信系统的开发.docx
- 文档编号:7521366
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:37
- 大小:436.18KB
基于winsock的局域网通信系统的开发.docx
《基于winsock的局域网通信系统的开发.docx》由会员分享,可在线阅读,更多相关《基于winsock的局域网通信系统的开发.docx(37页珍藏版)》请在冰豆网上搜索。
基于winsock的局域网通信系统的开发
重庆理工大学
课程设计
课程面向对象程序设计I
题目基于WinSock的局域
网通信系统的开发
1系统分析
1.1模块一
这个模块的功能是启动登录对话框,并且在启动后有登入,取消,申请帐号三个可以选择,若要登录则输入正确的帐号和密码即可,这是系统将传密码和帐号去验证是否正确,正确的话就可以登入到主对话框来(模块三),不正确的话会有重新输入的提示.如果选择申请帐号则会弹出申请帐号对话框(模块二).另外还可以点击取消(退出)按钮,则程序将关闭.
1.2模块二
申请帐号对话框弹出后,用户要输入长度范围内的昵称,以及长度方位内的密码,并且第二次输入的密码要与第一次输入的密码相同,如果不输入点确定也会报错,在确定完输入信息后,点击确定数据库将存放输入的信息,点击取消将回到登录界面.
1.3模块三
这个模块中我做的是窗口界面,也就是接口.进入主界面后,可以有更改状态,发送消息,删除好友,查找好友,个人设置,好友消息,退出这几个选项.点击更改状态可以选择自己的状态,一共有三种可供选择,点击查找好友后会弹出一个选择查找方式的窗口,选择方式查到好友后可查看好友资料并加好友,接下来可以与好友聊天,但必须选中好友后再点击发送信息,否则将弹出提示语,这点在点击好友信息按钮和删除好友按钮时也是如此,必须选中后才能操作.另外可以点击个人设置对自己的资料进行填写修改.点击退出会弹出一个确认退出对话框,再次确认后就将退出程序,点取消则返回主对话框.
2系统实现
2.1模块一
CP2PClientApptheApp;
unsignedintCP2PClientApp:
:
_seq_count=0;//消息号计数器
IM_Config_Parserg_fileobj("imclient.ini");//操作配置文件全局对象,配置文件名称imclient.ini
Message_Queue
Message_Queue
//全局udp通信对象
Udp_Daemong_udp_daemon;
#endif
//从配置文件读取配置信息
if(!
g_fileobj.open())
{
AfxMessageBox("打开配置文件imclient.ini失败!
");
return0;
}
charstrValue[MAX_STRING_LEN];
if(g_fileobj.get_string("im_appclient","im_server_ip",strValue,MAX_STRING_LEN))
m_ServerInfo.server_ip=ntohl(inet_addr(strValue));//服务器ip
if(g_fileobj.get_string("im_appclient","im_server_udp_port",strValue,MAX_STRING_LEN))
m_ServerInfo.server_port=atoi(strValue);//服务器端口号
if(g_fileobj.get_string("im_appclient","recv_producer_num",strValue,MAX_STRING_LEN))
m_ClientInfo.recv_producer_num=atoi(strValue);//接收消息线程数
if(g_fileobj.get_string("im_appclient","send_consumer_num",strValue,MAX_STRING_LEN))
m_ClientInfo.send_consumer_num=atoi(strValue);//发送消息线程数
if(g_fileobj.get_string("im_appclient","process_consumer_num",strValue,MAX_STRING_LEN))
m_ClientInfo.process_consumer_num=atoi(strValue);//处理消息线程数
if(g_fileobj.get_string("im_appclient","recent_ID",strValue,MAX_STRING_LEN))
m_ClientInfo.uid=atoi(strValue);//最近登录的用户帐号
m_ClientInfo.client_port=create_client_port();//获取客户端端口号
voidCLoginDlg:
:
OnLogin()
{
UpdateData(TRUE);//将界面内容传送给控件成员变量
if(m_nUID<9999)//用户帐号10000从开始
{
AfxMessageBox(CString("请正确输入用户帐号!
"));
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_UID));
return;
}
if(m_strPassword.IsEmpty())//密码不能为空
{
AfxMessageBox(CString("请输入密码!
"));
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD));
return;
}
//开始向服务器发送登录信息,然后根据服务器的返回信息
//判断输入的用户名和密码是否正确
IM_Headerheader;
header.cmd=IM_SESSION_LOGIN;
header.id=m_nUID;
header.seq=CP2PClientApp:
:
create_blk_seq();
header.reserved=0;
//开始构造数据包
IM_Message_Block*send_blk=newIM_Message_Block;
send_blk->write_header(header);//构造消息头
charszPassword[MAX_PASSWORD_LEN]="\0";
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);//将消息放入发送消息队列
}
voidCLoginDlg:
:
OnApplyUid()
{
CRegisterDlgdlg;//定义注册对话框对象
if(dlg.DoModal()==IDOK)//弹出注册对话框,如果用户在注册对话框中选择了"确定"按钮
{
//向服务器发送注册帐号消息
IM_Headerheader;
header.cmd=IM_ACCOUNT_REGISTER;
header.id=0;//现在还没有用户号
header.seq=CP2PClientApp:
:
create_blk_seq();
header.reserved=0;
//开始构造数据包
IM_Message_Block*send_blk=newIM_Message_Block;
send_blk->write_header(header);//构造消息头
charszNick[MAX_NICK_LEN+1]="\0";
strcpy(szNick,dlg.m_strNick.GetBuffer(0));
dlg.m_strNick.ReleaseBuffer();
send_blk->write_buffer(szNick,MAX_NICK_LEN+1);//
charszPassword[MAX_PASSWORD_LEN+1]="\0";
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);//将消息放入发送消息队列
}
}
voidCLoginDlg:
:
OnCancel()
{
CDialog:
:
OnCancel();//调用基类的OnCancel函数,关闭对话框,并返回IDCANCEL
}
LRESULTCLoginDlg:
:
OnAccountRegister(WPARAMwParam,LPARAMlParam)
{
IM_Message_Block*blk=(IM_Message_Block*)lParam;//转化传过来的参数
if(!
blk)
m_nUID=0;
else
{
UINT32uid=0;
blk->skip(sizeof(IM_Header));//跳过消息头
blk->read_UINT8(&m_ErrorCode);//读取错误码
blk->read_UINT32(&uid);//读取注册上的id
m_nUID=uid;
if(m_ErrorCode==IM_REGISTER_SUCESS&&m_nUID!
=0)
{
CStringstrTemp;
strTemp.Format("注册新帐号成功,新帐号为:
%u",m_nUID);
AfxMessageBox(strTemp);
}
elseif(m_ErrorCode==IM_REGISTER_ERROR||m_nUID==0)
{
AfxMessageBox(CString("注册新帐号失败!
"));
}
elseif(m_ErrorCode==IM_REGISTER_ERROR_DB)
{
AfxMessageBox(CString("注册帐号失败--数据库错误!
"));
}
deleteblk;
}
UpdateData(FALSE);//将成员变量值传给界面
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_UID));//将输入焦点定位到id输入框
return1;
}
LRESULTCLoginDlg:
:
OnSessionLogin(WPARAMwParam,LPARAMlParam)
{
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("密码错误!
"));
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD));
return0;
}
elseif(m_ErrorCode==IM_LOGIN_ERROR_UID_UNVALID)
{
AfxMessageBox(CString("该用户帐号不存在!
"));
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_UID));
return0;
}
elseif(m_ErrorCode==IM_LOGIN_ERROR_DB)
{
AfxMessageBox(CString("数据库错误,登录失败!
"));
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_UID));
return0;
}
elseif(m_ErrorCode==IM_LOGIN_SUCCESS)
{
theApp.m_ClientInfo.uid=m_nUID;
OnOK();//如果登录成功则调用基类的OnOK函数关闭对话框,并返回IDOK
}
}
return1;
}
2.2模块二
voidCRegisterDlg:
:
OnOK()
{
UpdateData(TRUE);//从界面向控件变量传送数据
if(m_strNick.IsEmpty())//昵称不能为空
{
AfxMessageBox(CString("请输入昵称!
"));//提醒用户
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_NICK));//定位输入焦点
return;
}
if(m_strPassword.IsEmpty())
{
AfxMessageBox(CString("请输入密码!
"));
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD));
return;
}
if(m_strPasswordAgain.IsEmpty())
{
AfxMessageBox(CString("请再次输入密码!
"));
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD_AGAIN));
return;
}
if(m_strNick.GetLength()>MAX_NICK_LEN)//昵称不能超长
{
CStringstrTemp;
strTemp.Format("昵称不能超过%d个字符!
",MAX_NICK_LEN);
AfxMessageBox(strTemp);
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_NICK));
return;
}
if(m_strPassword.GetLength()>MAX_PASSWORD_LEN)//密码不能超长
{
CStringstrTemp;
strTemp.Format("密码不能超过%d个字符!
",MAX_PASSWORD_LEN);
AfxMessageBox(strTemp);
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD));
return;
}
if(m_strPassword!
=m_strPasswordAgain)
{
AfxMessageBox(CString("两次密码输入不一致!
"));
GotoDlgCtrl((CWnd*)GetDlgItem(IDC_PASSWORD));
return;
}
CDialog:
:
OnOK();//调用基类的OnOk函数,关闭对话框,并返回IDOK
}
voidCRegisterDlg:
:
OnCancel()
{
//TODO:
Addextracleanuphere
CDialog:
:
OnCancel();
}
2.3模块三
voidCP2PClientDlg:
:
OnSelchangeOnlineStatus()
{
intnCurSel=m_ctrlOnlineStatus.GetCurSel();
if((nCurSel!
=theApp.m_ClientInfo.status)||(!
m_bIsLogin))
{
//开始发送改变在线状态信息
IM_Headerheader;
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=newIM_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);
//本地记录的状态也作相应的改动
theApp.m_ClientInfo.status=IM_STATUS_ONLINE;
}
elseif(nCurSel==1)
{
send_blk->write_UINT8(IM_STATUS_HIDE);
theApp.m_ClientInfo.status=IM_STATUS_HIDE;
}
elseif(nCurSel==2)
{
send_blk->write_UINT8(IM_STATUS_OUTWAY);
theApp.m_ClientInfo.status=IM_STATUS_OUTWAY;
}
elseif(nCurSel==3)
{
send_blk->write_UINT8(IM_STATUS_OFFLINE);
theApp.m_ClientInfo.status=IM_STATUS_OFFLINE;
}
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);//将消息放入发送消息队列
}
}
voidCP2PClientDlg:
:
OnSendMsg()
{
//查看是否选中了好友,如果选中了则顺便取出跟他的聊天记录
POSITIONpos=m_ctrlFriendList.GetFirstSelectedItemPosition();
if(!
pos)
{
AfxMessageBox(CString("请选择好友!
"));
return;
}
intnItem=m_ctrlFriendList.GetNextSelectedItem(pos);
//界面上显示的新消息数恢复为
m_ctrlFriendList.SetItemText(nItem,3,"0");
vector
CStringstrValue=m_ctrlFriendList.GetItemText(nItem,0);
unsignedintuid=atoi(strValue.GetBuffer(0));
strValue.ReleaseBuffer();
//查看该好友是否在线,如果在线顺便记住该好友的在线信息
BOOLbIsOnline=FALSE;
usr_info_online*friend_online_info=NULL;
vector
:
iteratorit=m_friend_online_list.begin();
for(;it!
=m_friend_online_list.end();it++)
{
friend_online_info=(usr_info_online*)*it;
if(friend_online_info->user_id==uid)
{
if(friend_online_info->status==IM_STATUS_ONLINE||friend_online_info->status==IM_STATUS_OUTWAY)
{
bIsOnline=TRUE;
break;
}
}
}
//弹出聊天对话框
CSMsgDlgdlg;
m_pChildWnd=&dlg;
m_nChatFriendID=uid;
//查找该好友的基本信息
vector
:
iteratorit_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;
if(friend_base_info->user_id==uid)
{
memcpy((cha
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 winsock 局域网 通信 系统 开发