当前位置: 首页 > news >正文

许昌建网站百度网页版主页

许昌建网站,百度网页版主页,做app和网站怎样,自考本科官网文章目录 前言一、添加客户端队列的参数初始化二、相关函数总结 前言 C打造局域网聊天室第九课: 客户端队列及其处理线程 一、添加客户端队列的参数初始化 在Server.cpp的 ListenThreadFunc()函数内的其他操作处实现客户端队列的添加。 首先进行部分参数的初始化…

文章目录

  • 前言
  • 一、添加客户端队列的参数初始化
  • 二、相关函数
  • 总结


前言

C++打造局域网聊天室第九课: 客户端队列及其处理线程


一、添加客户端队列的参数初始化

在Server.cpp的 ListenThreadFunc()函数内的其他操作处实现客户端队列的添加。
在这里插入图片描述
首先进行部分参数的初始化

CClientitem tItem; //定义一个客户端结点
tItem.m_Socket = accSock; //客户端的socket即为accept函数返回的accSock
tItem.m_surlp = inet_ntoa(clientAddr.sin_addr); // 客户端的IP包含在clientAddr结构中。inet_ntoa()函数将网络字节顺序的Ip转化为本机格式的字符串(192.192.1.1)
tItem.m_pMainWnd = pChartRoom; //主线程对话框指针

此时编译会报错: ‘inet_ntoa’: Use inet_ntop() or InetNtop() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings chartroom d:\vs2017项目\打造局域网聊天室\chartroom\chartroom\server.cpp 100

这是由于函数inet_ntoa过旧,此时需要在项目的属性中把SDL检查设置为否。
在这里插入图片描述

二、相关函数

后续的客户端队列的建立过程需要依赖一些函数,我们先实现这些函数,再回来继续客户端队列的建立过程。

聊天信息显示函数:
由于服务端每次都需要显示全部的聊天记录,而不是只显示当前的聊天记录,这就需要我们对之前的聊天内容进行保存。
首先对显示聊天内容的编辑框绑定一个成员变量。
在这里插入图片描述
设置一个变量名称,其他都为默认值
在这里插入图片描述
此时在chartroomDlg.h头文件内会自动声明该变量。
在这里插入图片描述
并且在chartroomDlg.h头文件中声明一个函数,用于声明聊天信息显示函数
在这里插入图片描述
在chartroomDlg.cpp源文件中实现函数ShowMsg()

// 实现聊天信息显示函数
void CchartroomDlg::ShowMsg(CString strMsg)
{m_MsgEdit.SetSel(-1, -1); // 将光标定位到文字的最后一个位置m_MsgEdit.ReplaceSel(strMsg + _T("\r\n")); // 将光标替换为strMsg + _T("\r\n")
}

从队列中删除客户端函数:
如果客户端关闭,此时服务端对应的客户端结点还在客户端队列中,那么就需要将客户端结点从客户端队列中删除。

同样先在chartroomDlg.h头文件内声明函数,使得类CchartroomDlg中包含成员函数
在这里插入图片描述
在chartroomDlg.cpp源文件中实现函数RemoveClientFromArray()

// 实现从队列删除客户端结点函数
void CchartroomDlg::RemoveClientFromArray(CClientitem in_Item) //参数为需要删除的客户端结点
{for (int idx = 0; idx < m_ClientArray.GetCount(); idx++) // 遍历客户端队列中的每一个结点{CClientitem tItem = m_ClientArray.GetAt(idx);if (tItem.m_Socket == in_Item.m_Socket && tItem.hThread == in_Item.hThread && tItem.m_surlp == in_Item.m_surlp) //队列中的该结点为需要删除的结点{m_ClientArray.RemoveAt(idx); // 删除结点}}
}

现在我们回到Server.cpp文件中,继续客户端队列的建立过程。
接下来初始化该客户端结点的线程句柄,同服务端创建线程,利用函数 CreateThread()。

// 客户端队列的添加CClientitem tItem; //定义一个客户端结点tItem.m_Socket = accSock; //客户端的socket即为accept函数返回的accSocktItem.m_surlp = inet_ntoa(clientAddr.sin_addr); // 客户端的IP包含在clientAddr结构中。inet_ntoa()函数将网络字节顺序的Ip转化为本机格式的字符串(192.192.1.1)tItem.m_pMainWnd = pChartRoom; //主线程对话框指针//  每一个客户端对应线程的句柄。说明:一个服务端对应多个客户端,在while死循环中调用accept接受一个客户端的连接之后,还可以在其他循环时接受// 其他客户端连接,每有一个客户端连接,我们创建一个客户端结点,将客户端结点的信息加入到客户端队列当中。//!!!!!!!!注意:该线程只进行监听端口,等待连接客户端的操作,接受连接客户端传来的消息等功能还需要新开一个线程进行处理,新开的线程与连接的客户端进行通信INT_PTR idx = pChartRoom->m_ClientArray.Add(tItem); // 将客户端结点放入队列中tItem.hThread = CreateThread(NULL, 0, ClientThreadProc, &(pChartRoom->m_ClientArray.GetAt(idx)), CREATE_SUSPENDED, NULL);// 初始化该客户端结点的线程句柄,注意第四个参数不要传递tItem的地址,CREATE_SUSPENDED表示该线程不要立即执行//这是因为如果有多个客户端来连接,tItem会一直变为最新连接的客户端结点,但是之前调用的以前连接的客户端结点也是用tItem,此时tItem已经存储的没有//之前连接的客户端结点的内容了pChartRoom->m_ClientArray.GetAt(idx).hThread = tItem.hThread; //将tItem的线程句柄同时赋给客户端队列中对应的客户端的线程句柄// 至此,该客户端的结点信息填充完毕ResumeThread(tItem.hThread); //与CREATE_SUSPENDED对应,在这里才开始执行被CREATE_SUSPENDED修饰的线程

下面介绍该线程的程序ClientThreadProc()函数的具体实现

// 实现客户端的创建线程函数,与接受的客户端进行通信的线程函数
DWORD WINAPI ClientThreadProc(LPVOID IpParameter) // 传入的参数为&(pChartRoom->m_ClientArray.GetAt(idx))
{CString strMsg;CClientitem m_ClientItem = *(CClientitem*)IpParameter; // 将传入的地址利用强制类型转换为客户端结点类型,不使用地址是怕误修改while (TRUE) // 用于监听该连接的客户端是否发送消息{if (SOCKET_Select(m_ClientItem.m_Socket, 100, TRUE)) //向缓冲区“偷看”一眼是否有客户端发过来的消息{TCHAR szBuf[MAX_BUF_SIZE] = { 0 }; // 申请缓冲区// recv函数:第一个参数为接收哪一个socket的数据;第二个参数为窄字节的缓冲区,存放接收过来的数据,要申请一块内存//第三个参数:缓冲区的长度;第四个参数平时为0即可。正常返回接收字节个数int iRet = recv(m_ClientItem.m_Socket, (char*)szBuf, MAX_BUF_SIZE,0); // 调用recv函数接受缓冲区中客户端发过来的消息if (iRet > 0){//正确,接收数据成功strMsg = szBuf; //为了操作方便(使用模板类函数),这里我们使用CString类型strMsg = _T("客户端:") + m_ClientItem.m_surlp + _T(">") + strMsg;m_ClientItem.m_pMainWnd->ShowMsg(strMsg); //利用在chartroom.cpp中实现的ShowMsg方法将信息显示}else // 接收数据失败,有错误或者客户端关闭了{// 关闭socketstrMsg = _T("客户端") + m_ClientItem.m_surlp + _T("离开了聊天室!");m_ClientItem.m_pMainWnd->ShowMsg(strMsg); //利用在chartroom.cpp中实现的ShowMsg方法将信息显示m_ClientItem.m_pMainWnd->RemoveClientFromArray(m_ClientItem); // 利用在chartroom.cpp中实现的RemoveClientFromArray方法在客户端队列中删去该客户端结点break;// 跳出循环,客户端已下线,退出线程}}Sleep(500);}return TRUE;
}

总结

C++打造局域网聊天室第九课: 客户端队列及其处理线程

http://www.wangmingla.cn/news/113175.html

相关文章:

  • 新人做网站不懂设计版面怎么办2023年重大时政热点
  • 路桥做网站网络营销策划书的范文
  • 做好网站建设工作优化大师的作用
  • 电子商务网站环境建设seo优化人员
  • 专业做网站建设的seo运营是什么
  • 网站公司建设网站长沙做搜索引擎的公司
  • 快站登录推广的软件
  • 学校网站建设实训总结广州市口碑全网推广报价
  • 网站不同浏览器css上海推广网络营销咨询热线
  • 网站标志的原则网站外链购买平台
  • 什么是网站交互性百度收录申请入口
  • 信用网站标准化建设哈尔滨网站建设
  • 购买平台有哪些宁波怎么优化seo关键词
  • 莱州网络建站hs网站推广
  • 东山县建设官方网站搜索引擎营销方式
  • 大连高新园区当阳seo外包
  • 网站建设入门书百度热榜实时热点
  • 如何把电脑改成服务器做网站南京响应式网站建设
  • 那个网站可以做学历认证网络营销技巧
  • 怎么用ppt做网站设计重庆网站推广专家
  • 供应链管理培训课程seo外包公司费用
  • 做网站-信科网络百度网登录入口
  • 如何在网站做404页面重庆seo技术博客
  • 网站开发的团队有哪些seo在线优化技术
  • b2c网站开发多少钱网络推广的渠道
  • 青海企业网站建设开发成品网站源码
  • wordpress跳转www新站seo优化快速上排名
  • 中国建设银行安徽省分行招聘网站百度游戏
  • 网站怎么去维护搜索引擎优化排名seo
  • 有哪些做网站的公司好站长工具查询