功能简介
私聊,群聊,查看在线好友,文件导入,日志导出 (MFC+Socket)
运行环境
vs2019
项目截图
- 服务器端
- 客户端
重要代码
服务器
- 开启、关闭服务器
void CServerDlg::OnBnClickedBtnStartStop()
{
// TODO: 在此添加控件通知处理程序代码
if (m_srvrStatus=="已停止") //状态为已停止,则要开启服务器监听端口
{
UpdateData();
CString log=_T("服务器已开启,等待客户端连接......");
m_ctrlChatRoomInfo.AddString(log);
WCHAR str[3];
m_ctrlMaxCnt.GetWindowTextW(str,3);//将最大客户端数 那个下拉窗口当前的数,拷贝到str中
m_maxClient=_ttoi(str);//将str从String转换到int
if (m_listenPort<1024)
{
MessageBox(_T("请选择大于1024的端口!"),_T("提示"),MB_ICONWARNING);
return;
}
if (!m_serverSocket.Create(m_listenPort))
{
MessageBox(_T("创建套接字出错!"),_T("错误"),MB_ICONERROR);
return;
}
if (!m_serverSocket.Listen())
{
MessageBox(_T("监听失败!"),_T("错误"),MB_ICONERROR);
return;
}
GetDlgItem(IDC_BTN_START_STOP)->SetWindowTextW(_T("停止"));
GetDlgItem(IDC_LISTENPORT)->EnableWindow(FALSE);
}
else //状态为正在监听,要停止监听
{
CString log = _T("服务器已关闭!!");
m_ctrlChatRoomInfo.AddString(log);
GetDlgItem(IDC_BTN_START_STOP)->SetWindowTextW(_T("启动"));
GetDlgItem(IDC_LISTENPORT)->EnableWindow(TRUE);
m_clientCnt = 0;
vector<CClientSocket *>::iterator iter;
for (iter = clientList.begin(); iter != clientList.end(); )
{
unsigned char buf[2]={
0};
buf[0]=SERVERCLOSE;
(*iter)->Send(buf,1);
(*iter)->Close();
delete (*iter);
iter=clientList.erase(iter);
}
clientList.clear();
m_serverSocket.Close();//关闭服务端套接字
}
m_srvrStatus=m_srvrStatus=="正在监听……"?"已停止":"正在监听……";
GetDlgItem(IDC_STATUS)->SetWindowTextW(m_srvrStatus);
UpdateData(FALSE);
}
- 服务器处理客户端发来的消息
void CServerDlg::ProcessData(CClientSocket *clientSocket)
{
unsigned char buf[MAX_BUFSIZE] = {
0 };
wchar_t wbuf[MAX_BUFSIZE] = {
0 };
wchar_t srcName[16] = {
0 }, dstName[16] = {
0 };
int len = clientSocket->Receive(buf, MAX_BUFSIZE);
vector<CClientSocket *>::iterator iter;
vector<CString>::iterator file_iter;//文件列表
CString log, usrName, usrNP, usrLove, usrAge, usrSex;
CTime tm;
bool undefine = true;//判断是否注册或是密码正确
CString data_c_srcName;
unsigned char data_buf[MAX_BUFSIZE] = {
0 };
CString strPath;
char CH_nameLength = NULL;
int IN_namelength = 0;
unsigned int strName_length = 0;
char chName_length;
string temp;
ifstream fin("user.txt", ios::in);//在这个路径下读入文件
ofstream fout("user.txt", ios::app);//在同一个路径下,如果注册成功则写入文件
switch (buf[0])
{
case NEWCLIENT: //收到用户要登录的消息
memcpy(wbuf, buf + 1, 16); //获取用户名
usrName = wbuf;
memcpy(wbuf, buf + 1, len - 1); //获取用户名和密码
usrNP = wbuf;
clientSocket->m_userName = usrName; //设置用户名
while (std::getline(fin, temp))//每次读一行的数据进入temp中。
{
if (usrNP == temp.c_str()) //用户名和密码都正确
{
undefine =