基于winsock的局域网通信系统的开发.docx
- 文档编号:6433448
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:54
- 大小:159.49KB
基于winsock的局域网通信系统的开发.docx
《基于winsock的局域网通信系统的开发.docx》由会员分享,可在线阅读,更多相关《基于winsock的局域网通信系统的开发.docx(54页珍藏版)》请在冰豆网上搜索。
基于winsock的局域网通信系统的开发
重庆理工大学
课程设计
课程面向对象程序设计I
题目基于WinSock的局域
网通信系统的开发
1系统分析
1.1功能模块分析
1.1.1模块一
消息实体类的实现模块
主要用来封装和存储在网络上传送消息(消息块),除此之外还主要负责管理消息块。
它主要记录的信息包括:
消息源地址、消息源端口、消息长度、消息头、消息块(消息数据区)、和游标()
由于记录读写消息块时的位置;该类主要提供的操作包括:
读写消息头操作、读写一个字节数据操作、读写两个字节数据操作、读写四个字节数据操作、读写指定字节的数据操作、提供消息块地址操作、游标操作、消息头操作。
在线用户信息类的实现模块
主要工作为记录和管理当前在线的所有用户,其中在线用户的信息包括:
用户号、外网地址、端口号、在线状态和密码;同时该类需要提供的操作包括:
赋值操作、判断两个用户是否相同的操作、更新用户在线信息的操作。
主函数模块
流程图:
服务器程序启动
读取配置文件
连接数据库
初始化socket通信
==
工作线程退出,主线程退出
1.1.2模块二
数据库
用户管理类的设计(完善服务器消息处理线程)模块
完善服务器消息处理线程中的用户管理类的设计,用户管理类包括用户当前的状态、查询用户的在线信息、设置用户的状态、新增在线的用户、删除在线用户、判断一个用户是否在线、统计在线人数、随机返回在线人数。
2系统实现
2.1模块一
实例系统开发前的准备模块
//定义公共头文件
#ifndefGLOBAL_DEFINE_H//为了防止重复定义而添加的宏
#defineGLOBAL_DEFINE_H//为了防止重复定义而添加的宏
//包含一些通用的头文件
#include
#include
#include
#include
usingnamespacestd;//引入标准C++命名空间
#defineMAX_STRING_LEN512//最大的字符串长度
#defineDB_SQL_ERROR0//SQL语句执行错误
#defineDB_SQL_SUCCESS1//SQL语句正确执行
#defineDB_SQL_NO_DATA_FOUND2//没有找到数据
#defineMAX_MSG_QUEUE_NUM1000//消息队列最大存放消息数
#defineSERVER_ID10000//服务器主动发出的消息头中的id号
#endif//GLOBAL_DEFINE_H,为了防止重复定义而添加的宏
//定义协议
#ifndefIM_PROTOCOL_H
#defineIM_PROTOCOL_H
//常量定义
constunsignedintSYSTEM_UID=10000;//系统主动发送的包里面的uid
constunsignedshortMAX_PACKET_LEN=3000;//最大包的长度
constunsignedshortMAX_TEXT_LEN=1500;//最大聊天长度
constunsignedshortMAX_CONTACT_NUM=512;//最大的好友数
constunsignedcharMAX_NICK_LEN=16;//最大别名长度
constunsignedcharMAX_EMAIL_LEN=32;//最大EMAIL长度
constunsignedcharMAX_NAME_LEN=16;//最大NAME长度
constunsignedcharMAX_COLLEGE_LEN=20;//最大学校长度
constunsignedcharMAX_PROFESSION_LEN=64;//最大专业长度
constunsignedcharMAX_NOTE_LEN=128;//最大个性说明长度
constunsignedcharMAX_TEL_LEN=12;//最大电话号码长度
constunsignedcharMAX_PASSWORD_LEN=16;//最大密码长度
constunsignedcharMAX_SEND_CONTACT_NUM=8;//每次发送的最大联系人个数,查找好友时用
constunsignedcharTIME_LEN=18;//时间占用的字节数
//基本数据结构定义
//改变字节对齐方式,在网络上传输的结构,必须使用字节对齐
#pragmapack
(1)
structIM_Header//定义数据包包头
{
unsignedshortcmd;//本条消息类型
unsignedintid;//发送这条消息的用户号
unsignedintseq;//消息号
unsignedintreserved;//保留字节
};
structusr_info_base//用户信息
{
unsignedintuser_id;//用户ID
unsignedcharpassword[MAX_PASSWORD_LEN+1];//密码
unsignedcharnick[MAX_NICK_LEN+1];//昵称
unsignedshortpicture;//头像的索引号
unsignedcharname[MAX_NAME_LEN+1];//姓名
unsignedchargengder;//性别男=0,女=1
unsignedcharage;//年龄
unsignedcharemail[MAX_EMAIL_LEN+1];//邮件
unsignedchartelephone[MAX_TEL_LEN+1];//电话
unsignedcharcollege[MAX_COLLEGE_LEN+1];//毕业院校
unsignedcharprofession[MAX_PROFESSION_LEN+1];//专业
unsignedcharnote[MAX_NOTE_LEN+1];//个性说明
};
structusr_info_online//在线用户信息
{
unsignedintuser_id;//用户ID
unsignedintIP;//外网IP
unsignedshortim_udp_port;//外网端口
unsignedcharstatus;//状态等级在线=0,隐身=1,离开=2,离线=3
};
#pragmapack()
structIM_server_info//服务器信息
{
unsignedintip;//服务器ip
unsignedshortport;//服务器端口
unsignedintuser_online;//在线用户数量
};
//协议定义
enumIM_CMD//定义协议命令码
{
//帐号管理
IM_ACCOUNT_REGISTER=0x1000,//注册C<-->S,0x1000
IM_ACCOUNT_SET_INFO,//更新信息C-->S,0x1001
//会话管理
IM_SESSION_LOGIN,//登录C<-->S,0x1002
IM_SESSION_STATUS_CHANGE,//状态改变C<-->S,0x1003
IM_SESSION_HEARTBEAT,//心跳C<-->S,0x1004
IM_SESSION_LOGOUT,//退出C-->S,0x1005
//联系人管理
IM_CONTACT_SEARCH,//查找C<-->S,0x1006
IM_CONTACT_ADD,//添加C<-->S,0x1007
IM_CONTACT_DEL,//删除C-->S,0x1008
IM_CONTACT_GET_LIST,//取列表C<-->S,0x1009
IM_GET_ONLINE_INFO,//取在线信息C<-->S,0x100A
//简单聊天
IM_SCHAT_MSG,//文本聊天C<-->C,0x100B
};
//添加联系人子命令
#defineIM_CONTACT_ADD_REQ0x00//请求C1<-->S
#defineIM_CONTACT_ADD_NOTIFY0x01//通知S<-->C2
//用户会话状态
#defineIM_STATUS_ONLINE0x00//用户在线
#defineIM_STATUS_HIDE0x01//用户隐身
#defineIM_STATUS_OUTWAY0x02//用户离开
#defineIM_STATUS_OFFLINE0x03//用户离线
//联系人查找类型
#defineIM_SEARCH_ID0x00//根据号码查找联系人
#defineIM_SEARCH_NICK0x01//根据昵称查找联系人
#defineIM_SEARCH_RANDOM0x02//查找在线用户
//注册错误码
#defineIM_REGISTER_SUCESS0x00//注册成功
#defineIM_REGISTER_ERROR0x01//注册失败
#defineIM_REGISTER_ERROR_DB0x02//注册失败,数据库错误
//更新信息错误码
#defineIM_SET_INFO_SUCCESS0x00//更新跟人信息成功
#defineIM_SET_INFO_ERROR0x01//更新个人信息失败
#defineIM_SET_INFO_ERROR_DB0x02//更新个人信息失败,数据库错误
//登陆错误码
#defineIM_LOGIN_SUCCESS0x00//登录成功
#defineIM_LOGIN_ERROR_PSW0x01//登录失败,密码错误
#defineIM_LOGIN_ERROR_UID_UNVALID0x02//用户ID无效
#defineIM_LOGIN_ERROR_DB0x03//数据库错误
//增加联系人错误码
#defineIM_CONTACT_ADD_SUCCESS0x00//添加联系人成功
#defineIM_CONTACT_ADD_ERROR0x01//添加联系人失败
//删除联系人错误码
#defineIM_CONTACT_DEL_SUCCESS0x00//删除联系人成功
#defineIM_CONTACT_DEL_ERROR0x01//删除联系人失败
#endif//IM_PROTOCOL_H
消息实体类的实现模块
#ifndefIM_MESSAGE_BLOCK_H//避免重复定义
#defineIM_MESSAGE_BLOCK_H
#include"IM_Protocol.h"
#include
classIM_Message_Block
{
public:
IM_Message_Block()
:
src_ip_(0)
src_port_(0)
length_(0)
cursor_(0)
header_((IM_Header*)data_)//消息头的地址就是整个数据包中数据块的首地址
{
}
~IM_Message_Block(void)
{
}
public:
IM_Header*get_header()//获取消息头指针
{
returnheader_;
}
voidset_header(constIM_Header*header)//设置消息头
{
memcpy((char*)header_,header,sizeof(IM_Header));//内存拷贝
}
unsignedchar*get_data()//获取数据块首地址
{
returndata_;
}
unsignedshortget_cursor()//获取光标
{
returncursor_;
}
voidread_header(IM_Header&header)//读取
{
header.cmd=ntohs(header_->cmd);
header.id=ntohl(header_->id);
header.seq=ntohl(header_->seq);
header.reserved=ntohl(header_->reserved);
cursor_+=sizeof(IM_Header);
}
voidread_UINT8(unsignedchar*value)
{
*value=*(data_+cursor_);
cursor_++;
}
voidread_UINT16(unsignedshort*value)
{
*value=ntohs(*((unsignedshort*)(data_+cursor_)));
cursor_+=2;
}
voidread_UINT32(unsignedint*value)
{
*value=ntohl(*((unsignedint*)(data_+cursor_)));
cursor_+=4;
}
voidread_buffer(char*value,intlength)
{
memcpy((char*)value,(char*)data_+cursor_,length);
cursor_+=length;
}
voidwrite_header(constIM_Header&header)
{
header_->cmd=htons(header.cmd);
header_->id=htonl(header.id);
header_->seq=htonl(header.seq);
header_->reserved=htonl(header.reserved);
cursor_+=sizeof(IM_Header);
}
voidwrite_UINT8(unsignedcharvalue)
{
*(data_+cursor_)=value;
cursor_++;
}
voidwrite_UINT16(unsignedshortvalue)
{
*(unsignedshort*)(data_+cursor_)=htons(value);
cursor_+=2;
}
voidwrite_UINT32(unsignedintvalue)
{
*(unsignedint*)(data_+cursor_)=htonl(value);
cursor_+=4;
}
voidwrite_buffer(constchar*value,intlength)
{
memcpy((char*)data_+cursor_,value,length);
cursor_+=length;
}
voidskip(intlength)
{
cursor_+=length;
}
voidback(intlength)
{
cursor_-=length;
}
voidset_cursor(unsignedshortcursor)
{
cursor_=cursor;
}
public:
//以下三个变量外部需要访问
unsignedintsrc_ip_;
unsignedshortsrc_port_;
unsignedintlength_;
private:
unsignedchardata_[MAX_PACKET_LEN];
IM_Header*header_;
unsignedshortcursor_;
};
#endif//IM_MESSAGE_BLOCK_H
在线用户信息类的实现模块
//定义IM_User_Block类的头文件
#ifndefIM_USER_BLOCK_H
#defineIM_USER_BLOCK_H
#include"IM_Protocol.h"
classIM_User_Block
{
public:
IM_User_Block(constunsignedint&uid=0,constunsignedint&ip=0,constunsignedshort&port=0,constunsignedchar&status=0,constunsignedchar*pwd=0);
IM_User_Block&operator=(constIM_User_Block&ublk);//拷贝构造函数
booloperator==(constIM_User_Block&ublk)const;//重载==运算符,判断两个用户id是否一致
voidUpdate_Info(constIM_User_Block&ublk);//更新用户信息
unsignedint_uid;//ID
unsignedint_ip;//IP
unsignedshort_port;//im外网udp端口
unsignedchar_status;//在线状态在线=0,隐身=1,离开=2,离线=3
unsignedchar_pwd[MAX_PASSWORD_LEN+1];//password
};
#endif//IM_USER_BLOCK_H
//新建IM_User_Block的源文件
#include"Global_Define.h"
#include"IM_User_Block.h"
IM_User_Block:
:
IM_User_Block(constunsignedint&uid,constunsignedint&ip,constunsignedshort&port,constunsignedchar&status,constunsignedchar*pwd)
:
_uid(uid),_ip(ip),_port(port),_status(status)
{
if(pwd)
{
strcpy((char*)_pwd,(char*)pwd);
_pwd[MAX_PASSWORD_LEN]='\0';
}
else
memset(_pwd,0,MAX_PASSWORD_LEN+1);
}
IM_User_Block&IM_User_Block:
:
operator=(constIM_User_Block&ublk)
{
this->_uid=ublk._uid;
this->_ip=ublk._ip;
this->_port=ublk._port;
this->_status=ublk._status;
strcpy((char*)this->_pwd,(char*)ublk._pwd);
return*this;
}
boolIM_User_Block:
:
operator==(constIM_User_Block&ublk)const
{
returnthis->_uid==ublk._uid;
}
voidIM_User_Block:
:
Update_Info(constIM_User_Block&ublk)
{
if(this->_uid==ublk._uid)
{
this->_ip=ublk._ip;
this->_port=ublk._port;
this->_status=ublk._status;
strcpy((char*)this->_pwd,(char*)ublk._pwd);
}
}
实例系统输入/输出类的实现模块
//服务器配置文件信息、
[im_appserver]
db_ip=127.0.0.1
db_port=3306
db_name=P2PServerDB
db_usr=myid
db_pwd=myid
im_server_udp_port=5402
recv_producer_num=1
send_consumer_num=1
process_consumer_num=2
//输入/输出类的实现
//***************IM_Config_Parser头文件***************************
#ifndefIM_CONFIG_PARSER_H
#defineIM_CONFIG_PARSER_H
#include"Global_Define.h"
#include
classIM_Config_Parser
{
public:
IM_Config_Parser(constchar*file_name);
virtual~IM_Config_Parser(void);
public:
boolopen();
//根据信息类型strType和键strKey获取键值strValue
boolget_string(constchar*strType,constchar*strKey,char*strValue,constint&nMaxLen);
//根据信息类型strType和键strKey更新键值
boolupdate_string(constchar*str
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 winsock 局域网 通信 系统 开发