MFC中基于TCP/UDP协议的网络聊天室(ODBC链接MySQL、基于对话框、简易网络聊天室、TCP/UDP协议)

MFC中基于TCP/UDP协议的网络聊天室(ODBC链接MySQL、基于对话框、简易网络聊天室、TCP/UDP协议)

前言

这个代码是MFC中基于TCP/UDP协议的简易网络聊天室,主要实现的功能是不同客户端之间可以互相发送消息, 而且所有消息都存储在数据库中,客户端用户可以对自己所发送过的消息进行查询。服务器可以对客户端进行相应的管理。程序链接了MySQL数据库,VS和数据的链接这块儿不在赘述。
程序代码链接 https://download.csdn.net/download/eq_cyc/11966503

环境说明

编译环境:VS2012
数据库:MySQL

核心代码

登录界面

这块儿是一个简单的登录界面,UDP协议和TCP协议的基本相同,主要算法在三次登录和链接数据库。先上图:

在这里插入图片描述
登录代码:


void dlg::OnBnClickedlogin()
{
GetDlgItem(IDC_EDIT1)->GetWindowText(user1);
GetDlgItem(IDC_EDIT2)->GetWindowText(password);
//将两个控件里的值作为数据库查询条件
if(user1.IsEmpty()||password.IsEmpty())
{
	AfxMessageBox(_T("用户名或密码不能为空!"));
	return;
}

//进行数据库查询,user和password一致则执行登录操作
UpdateData();
m_num++;
CString strSQL;
strSQL.Format(_T("select * from serverlogin where name ='%s' and password = '%s'"),user1,password);

if(!recordset.Open(AFX_DB_USE_DEFAULT_TYPE,strSQL))
{
	MessageBox(_T("打开数据库失败!"),_T("数据库错误"),MB_OK);
	return ;
}

if(recordset.GetRecordCount()==0)
{
	if(m_num == 3)
	{
		MessageBox(_T("密码错误3次,自动退出!"));
		exit(0);
	}
	else{
		recordset.Close();
		MessageBox(_T("密码错误,请重新输入!"));
		password="";
		UpdateData(FALSE);
	}
}
else{
	//如果组合框控件选择的是TCP_Client,则登录到页面1***********************************
	if (m_cb.GetCurSel()==0)
	{
		MessageBox(_T("登录成功TCP_Server!"));
		recordset.Close();
		m_dataBase.Close();
		CDialog::OnOK();
		ClineDlg dlg;
		theApp.m_pMainWnd = &dlg;
		dlg.DoModal();
	}	//如果组合框控件选择的是UDP_Client,则登录到页面2***********************************
	else if(m_cb.GetCurSel()==1)
	{
		MessageBox(_T("登录成功UDP_Server!"));
		recordset.Close();
		m_dataBase.Close();
		//关闭登录窗口
		CDialog::OnOK();
		UDPDlg dlg;
		theApp.m_pMainWnd = &dlg;
		dlg.DoModal();				
	}
}
}

数据库配置

在这里插入图片描述

注册界面

在这里插入图片描述

TCP服务端

在这里插入图片描述
TCP协议服务器端这一套必须写全了:
1.Creat()Create 方法已经包含了 Bind 方法,如果是以 Create 方法创建socket的前提下不能再调用 Bind ,要不一定出错。
2.Listen()
3.Accept()

新建一个类,继承CSocket类,类名为CServerSocket,
CServerSocket核心代码:


//添加上线用户,套接字接受到连接请求时触发该事件
//以通知侦听套接字它可以通过调用accept成员函数接受挂起的连接请求。
void CServerSocket::OnAccept(int nErrorCode)
{
	m_pDlg->AddClient();  //调用对话框类的AddClient方法:添加新的连接用户
	CSocket::OnAccept(nErrorCode);
}

// 删除下线用户,套接字关闭时触发该事件
void CServerSocket::OnClose(int nErrorCode)
{
	m_pDlg->RemoveClient(this); //RemoveClient:移除客户端
	CSocket::OnClose(nErrorCode);
}

// 接收数据,,套接字上有数据被接受时触发该事件
void CServerSocket::OnReceive(int nErrorCode)
{
	m_pDlg->RecvData(this);  //调用对话框类的RecvData方法:接受客户端发来的消息
	CSocket::OnReceive(nErrorCode);
}


void CServerSocket::OnSend(int nErrorCode)
{
	// TODO: 在此添加专用代码和/或调用基类

	CSocket::OnSend(nErrorCode);
}

创建服务器端的套接字Creat(),并且监听Listen(),打开服务器

void ClineDlg::startServer()
{
	CString cport;
	//获取服务器的端口号
	GetDlgItemText(IDC_SERVERPORT,cport);
	//端口号的字符串转换为数字
	int port = _ttoi(cport);
	//如果没有填写端口号,则默认的端口号为8080
	if (port == 0)
	{
		m_port = 8080;
	}
	else
	{
		m_port = port;
	}

	//如果当前服务器的状态为开启,则关闭服务器m_connect初始为false
	if (m_connect)
	{
		//关闭服务器的socket
		delete m_listenSocket;
		m_listenSocket = NULL;
		m_connect = false;
		SetDlgItemText(IDC_BN_SERVER_START, _T("打开服务器"));
		UpdateEvent(_T("系统关闭服务器."));
		//关闭控件的只读状态
		m_editPort.SetReadOnly(FALSE);
		//设置“发送”按钮为不可用
		m_buttonSend.EnableWindow(FALSE);
		return;
	}
	//否则就打开服务器
	m_listenSocket = new CServerSocket();
	m_listenSocket->m_pDlg = this;
	m_listenSocket->m_userName = _T("TCP服务器");
	
	// 指定对话框为主对话框,不能少了这句
	UpdateData(true);
	// 创建服务器的套接字,IP地址默认本机IP
	if (!m_listenSocket->Create(m_port))	//bind绑定端口
	{
		AfxMessageBox(_T("创建套接字错误!"));
		m_listenSocket->Close();
		return;
	}
	if (!m_listenSocket->Listen())
	{
		AfxMessageBox(_T("监听失败!"));
		m_listenSocket->Close();
		return;
	}
	m_connect = true;
	SetDlgItemText(IDC_BN_SERVER_START, _T("关闭服务器"));
	//更新聊天窗口中的消息
	UpdateEvent(_T("系统打开服务器."));
	//将服务器端口号的控件设置为只读状态
	if(port == 0)
	{
		m_editPort.SetWindowTextW(_T("8080"));
	}
	else 
	{
		m_editPort.SetWindowTextW(cport);
	}
	m_editPort.SetReadOnly(TRUE);
	//设置“发送”按钮为可用
	m_buttonSend.EnableWindow(TRUE);
}

接收由客户端发来的消息

void ClineDlg::RecvData(CServerSocket* pSocket)
{
	char* pData = NULL;
	pData = new char[1024];
	memset(pData, 0, sizeof(char)* 1024);
	UCHAR leng = 0;
	CString str;
	//Receive为CSocket中的方法,用于服务器接收消息
	//pData接受数据的缓冲区
	//1024:缓冲区的长度
	//0:函数调用模式
	if (pSocket->Receive(pData,1024,0) != SOCKET_ERROR)
	{
		str = pData;
		//接受消息后可以将消息转发给所有客户端或者指定客户端translateMsg()转发
		translateMsg(str, pSocket);
	}
	delete[] pData;
	pData = NULL;
}

添加新的客户端,调用Accept()函数

void ClineDlg::AddClient()
{
	CServerSocket *pSocket = new CServerSocket;  //创建一个套接字
	pSocket->m_pDlg = this;
	m_listenSocket->Accept(*pSocket);  //接受客户端套接字连接
	//CAsyncSocket::AsyncSelect调用此成员函数以请求套接字的事件通知。
	pSocket->AsyncSelect(FD_READ | FD_WRITE | FD_CLOSE);
	//AddTail将新元素的列表添加到此列表的结尾。
	m_clientList.AddTail(pSocket);  //将套接字添加到列表容器中
	m_userCount = m_clientList.GetCount();
	UpdateData(false);
}

给客户端发送消息:

void ClineDlg::SendMSG()
{
	CString  msg;
	//获取消息框中的字符串
	GetDlgItemText(IDC_EDITMSG, msg);
	//获取当前选中的用户的下标(比如选中了某个人或者选中了“所有人”)
	int selectIndex = m_users.GetCurSel();
	if(selectIndex == -1)
	{
		MessageBox(_T("请在聊天室中选择发送对象!"));
		return ;
	}
	if(msg == _T(""))
	{
		MessageBox(_T("请输入要发送的内容!"));
		return ;
	}
	CString usermsg;
	//获取该下标的字符串名称
	m_users.GetText(selectIndex, usermsg);
	if (usermsg == "所有人")
	{
		usermsg = _T("MEVERY") + msg;
	}
	else
	{
		usermsg = _T("M") + usermsg + _T(" ") + msg;
	}
	translateMsg(usermsg, this->m_listenSocket);
}

TCP客户端

TCP协议的客户端代码,重点是创建套接字Creat(),和连接服务器Connect()。然后利用Send()函数给服务器发送消息,利用Receive函数来接受消息,并且将接受到的信息进行拆分,分别在聊天室列表和聊天窗口进行显示。接受到了服务器端发送的消息后,同时会将消息进行存储。数据存储在MySQL数据库中,显示历史聊天记录是对数据库进行查询的一个操作,按用户名进行查询,将查询出来的结果显示在聊天记录窗口中。

在这里插入图片描述
下面是核心代码,进行讲解:
连接服务器,会进行客户端套接字的创建和连接工作。

void ClineClientDlg::ConnectServer()
{
	GetDlgItemText(IDC_USERNAME, m_userName);
	//如果已经连接,则断开服务器
	if (m_connect)
	{
		//关闭并且删除客户端的socket
		m_connect = false;
		m_pSock->Close();
		delete m_pSock;  //删除套接字
		m_pSock = NULL;
		m_ConPC.SetWindowTextW(_T("连接服务器"));
		m_buttonSend.EnableWindow(FALSE);
		m_buttonShowHistory.EnableWindow(FALSE);
		UpdateData(false);
		return;
	}
	//否则连接服务器
	else
	{
		//在这里创建新的socket
		m_pSock = new CClientSocket();
		//创建套接字
		if (!m_pSock->Create())
		{
			AfxMessageBox(_T("创建套接字失败!"));
			return;
		}
	}
	//获得ip控件的ip
	BYTE f1, f2, f3, f4;
	((CIPAddressCtrl*)GetDlgItem(IDC_SERVERIPADDRESS))->GetAddress(f1, f2, f3, f4);
	m_strServerip.Format(_T("%d.%d.%d.%d"), f1, f2, f3, f4);
	m_port = GetDlgItemInt(IDC_SERVERPORT);
	m_strServerip = _T("127.0.0.1");
	//TCP服务器为8080
	//用m_strServerip和m_port来验证是否成功连接到服务器
	if (!m_pSock->Connect(m_strServerip, m_port))
	{
		AfxMessageBox(_T("连接服务器失败!"));
		return;
	}
	else
	{
		AfxMessageBox(_T("连接服务器成功!"));
		//成功连接上了服务器!!
		m_connect = true;
		int n = 0;
		CString userName;
		userName = _T("MUSERNAME") + m_userName;
		//宽字节转多字节,确定要发送的字符串将占据多少个宽度的char
		n = WideCharToMultiByte(CP_OEMCP, 0, userName, -1, NULL, 0, 0, FALSE);
		char* pBuff = new char[n];
		memset(pBuff, 0, n);
		//宽字节转多字节,将要发送的字符串转化为字节流
		WideCharToMultiByte(CP_OEMCP, 0, userName.GetBuffer(0), n, pBuff, n, 0, FALSE);
		//通过socket发送多字节流连接
		m_pSock->SendMSG(pBuff, n);
		delete[] pBuff;
		m_ConPC.SetWindowTextW(_T("断开服务器"));
		m_buttonSend.EnableWindow(TRUE);
		m_buttonShowHistory.EnableWindow(TRUE);
		UpdateData(false);
	}
}

给服务器发送消息:

void ClineClientDlg::SendMsg()
{
	CString  msg;
	//获得消息框里的字符串
	GetDlgItemText(IDC_EDIT_MSG, msg);
	int selectIndex = m_userslist.GetCurSel();
	if(selectIndex == -1)
	{
		MessageBox(_T("请在聊天室中选择发送对象!"));
		return ;
	}
	if(msg == _T(""))
	{
		MessageBox(_T("请输入要发送的消息内容!"));
		return ;
	}
	CString usermsg;
	m_userslist.GetText(selectIndex, usermsg);
	if (usermsg == "所有人")
	{
		usermsg = _T("MEVERY") + msg;
	}
	else
	{
		usermsg = _T("M") + usermsg + _T(" ") + msg;
	}
	if (!usermsg.IsEmpty())
	{
		//未连接服务器则不执行
		if (!m_connect)
		{
			return;
		}
		UpdateData(true);
		GetDlgItemText(IDC_EDIT_MSG, m_DataSend);
		if (m_DataSend != "")
		{
			int n = 0;
			m_DataSend = usermsg;
			//通过将宽字节转换成多字节来获得多字节的位数
			n = WideCharToMultiByte(CP_OEMCP, 0, m_DataSend, -1, NULL, 0, 0, FALSE);
			char* pBuff = new char[n];
			//初始化数组
			memset(pBuff, 0, n);
			//将宽字节转换成多字节
			WideCharToMultiByte(CP_OEMCP, 0, m_DataSend.GetBuffer(0), n, pBuff, n, 0, FALSE);
			//发送消息
			m_pSock->SendMSG(pBuff, n);
			//2019-10-26
			delete[] pBuff;
		}
	}
}

每更改一次聊天窗口的内容,就更新数据库对应的聊天记录

void ClineClientDlg::updateDataBase(CString newStr)
{
	if(m_pSock == NULL)
	{
		return ;
	}
	CTime curTime;
	curTime = CTime::GetCurrentTime(); //获取系统时间
	CString strCurTime;                 
	strCurTime=curTime.Format(_T("%Y-%m-%d %H:%M:%S"));
	CString str;
	str.Format(_T("insert history value('%s','%s','%s')"),m_userName,newStr,strCurTime);
	m_dataBase.ExecuteSQL(str);
}

更新聊天室列表

void ClineClientDlg::UpdateUsers(CString str, int index)
{
	str = str.Right(str.GetLength()-strlen("MUPDATEUSERLIST"));
	CStringArray *strArray = translateUsersStr(str);
	int size = strArray->GetSize();
	m_userslist.ResetContent();
	m_userslist.AddString(_T("所有人"));
	for (int i = 0; i < size; i++)
	{
		m_userslist.AddString(strArray->GetAt(i));
	}
}

UDP服务端

UDP与TCP最大的区别是UDP是无连接的网络协议 ,因此每次发送消息的时候只需要对方的IP和端口号就可以发送过去了。UDP服务器需要创建套接字,但是并不需要监听和连接,因此UDP服务器狭义上来讲也可以是一个客户端,它主要是进行一个消息转发的功能。所有的客户端同时给这个端口为8080(8080可以自己设置)的服务器发送消息,服务器收到消息后进行转发

核心代码:

打开服务器:进行套接字的创建Create(m_port,SOCK_DGRAM,NULL),类型为SOCK_DGRAM数据报格式。

void UDPDlg::OnBnClickedBnServerStart()
{
CString cport;
	//获取服务器的端口号
	GetDlgItemText(IDC_SERVERPORT,cport);
	//端口号的字符串转换为数字
	int port = _ttoi(cport);
	//如果没有填写端口号,则默认的端口号为8080
	if (port == 0)
	{
		m_port = 8080;
	}
	else
	{
		m_port = port;
	}
	//如果当前服务器的状态为开启,则关闭服务器,,,m_connect初始为false
	if (m_connect)
	{
		//关闭服务器的socket
		delete m_pServerSocket;
		m_pServerSocket = NULL;
		m_connect = false;
		SetDlgItemText(IDC_BN_SERVER_START, _T("打开服务器"));
		UpdateEvent(_T("系统关闭服务器."));
		//关闭控件的只读状态
		m_editPort.SetReadOnly(FALSE);
		//设置“发送”按钮为不可用
		m_buttonSend.EnableWindow(FALSE);
		return;
	}
	//否则就打开服务器
	// 创建服务器的套接字,IP地址默认本机IP
	m_pServerSocket = new UDPServerSocket();
	m_pServerSocket->m_pdlg = this;
	m_pServerSocket->m_userName = _T("UDP服务器");
	UpdateData(true);
	m_pServerSocket->Create(m_port,SOCK_DGRAM,NULL);  //创建本地套接口
	m_connect = true;
	SetDlgItemText(IDC_BN_SERVER_START, _T("关闭服务器"));
	//更新聊天窗口中的消息
	UpdateEvent(_T("系统打开服务器."));
	if(port == 0)
	{
		m_editPort.SetWindowTextW(_T("8080"));
	}
	else 
	{
		m_editPort.SetWindowTextW(cport);
	}	
	//将服务器端口号的控件设置为只读状态
	m_editPort.SetReadOnly(TRUE);
	//设置“发送”按钮为可用
	m_buttonSend.EnableWindow(TRUE);
}

接受客户端的连接,并且对接受到的数据进行处理。用户名添加在聊天室列表中,消息更新在聊天窗口。UDP协议的接受用的是ReceiveFrom(这块儿也不同与TCP的Receive),发送消息用的是SendTo(不同于TCP协议的Send)

void UDPDlg::OnBnClickedSendmsg()
{
	CString  msg;
	//获取消息框中的字符串
	GetDlgItemText(IDC_EDITMSG, msg);
	//获取当前选中的用户的下标(比如选中了某个人或者选中了“所有人”)
	int selectIndex = m_users.GetCurSel();
	if(selectIndex == -1)
	{
		MessageBox(_T("请在聊天室中选择发送对象!"));
		return ;
	}
	if(msg == _T(""))
	{
		MessageBox(_T("请输入要发送的内容!"));
		return ;
	}
	CString usermsg;
	//获取该下标的字符串名称
	m_users.GetText(selectIndex, usermsg);
	if (usermsg == "所有人")
	{
		usermsg = _T("MEVERY") + msg;
	}
	else
	{
		usermsg = _T("M") + usermsg + _T(" ") + msg;
	}
	translateMsg(usermsg,this->m_pServerSocket, m_ClientAddr);
			//发送消息

}
void UDPDlg::RecvData(UDPServerSocket* pSocket)
{
	CString str;
	TCHAR buff[4096];  //定义接受数据的缓冲区
	int nRead;
	ClientAddr  sendServerAddr;

	nRead = pSocket -> ReceiveFrom(buff,4096,sendServerAddr.strIPAddr,sendServerAddr.uiPort);

	CString tmpstr = buff;
	if (tmpstr.Left(9) == _T("MUSERNAME"))
	{
		//保存用户Socket,以便后来发消息时使用
		m_clientList.AddTail(pSocket);
		tmpstr = tmpstr.Mid(9);//去掉前缀"MUSERNAME",取出新登录的用户名
		sendServerAddr.strUserName = tmpstr;
		m_ClientAddrList.Add(sendServerAddr);
	}
	else
	{
		for (int i = 0; i < m_ClientAddrList.GetSize(); i++)
		{
			ClientAddr& tempClient = m_ClientAddrList.ElementAt(i);
			if (tempClient.strIPAddr==sendServerAddr.strIPAddr && tempClient.uiPort == sendServerAddr.uiPort)
			{
				sendServerAddr.strUserName = tempClient.strUserName;
				break;
			}
		}
	}

	if (nRead != SOCKET_ERROR)
	{
		str=buff;
		translateMsg(str, pSocket, sendServerAddr);
	}
	
	if(nRead == SOCKET_ERROR){
	    return;
	}
}

其余部分都和TCP协议的服务器端代码类似,这块儿不在给出。

UDP客户端

UDP客户端和服务端的代码类似,也是进行套接字的创建,消息的发送。具体代码如下:

连接服务器

void UDPClientDlg::OnBnClickedLnetoserver()
{
	//获得ip控件的ip
	BYTE f1, f2, f3, f4;
	((CIPAddressCtrl*)GetDlgItem(IDC_SERVERIPADDRESS))->GetAddress(f1, f2, f3, f4);
	m_strServerip.Format(_T("%d.%d.%d.%d"), f1, f2, f3, f4);
	m_port = GetDlgItemInt(IDC_SERVERPORT);
	GetDlgItemText(IDC_USERNAME, m_userName);
	//如果已经连接,则断开服务器
	if (m_connect)
	{
		//关闭并且删除客户端的socket
		m_connect = false;
		m_pClientSock->Close();
		delete m_pClientSock;  //删除套接字
		m_pClientSock = NULL;
		m_ConPC.SetWindowTextW(_T("连接服务器"));
		m_buttonSend.EnableWindow(FALSE);
		m_buttonShowHistory.EnableWindow(FALSE);
		UpdateData(false);
		return;
	}
	//否则连接服务器
	else
	{
		CString m1,m2,m3;
		GetDlgItemText(IDC_SERVERIPADDRESS,m1);
		GetDlgItemText(IDC_USERNAME,m2);
		GetDlgItemText(IDC_SERVERPORT,m3);

		if (m1.IsEmpty()||m2.IsEmpty()||m3.IsEmpty())
		{
			AfxMessageBox(_T("请输入IP和Port"));
		}
		else
		{	
				//创建套接字
			m_pClientSock = new UDPClientSocket(this); //初始化套接字的成员变量
			//创建套接字
			if (!m_pClientSock -> Create(m_port,SOCK_DGRAM))  //创建套接字,SOCK_DGRAM:数据报套接字
			{
				AfxMessageBox(_T("创建套接字失败!"));
				return;
			}
					AfxMessageBox(_T("创建套接字成功!!!"));
			SocketAddr myAddr;

			AfxMessageBox(_T("连接服务器成功!"));
		
			//成功连接上了服务器!!
			m_connect = true;
			UpdateData(TRUE);

//*******************************************************************************************
			//通过socket发送数据报连接
			CString userName;
			userName = _T("MUSERNAME") + m_userName;

			m_pClientSock->SendTo((LPCTSTR)userName, userName.GetLength()*8, m_ServerAddr.uiPort, m_ServerAddr.strIPAddr);
//*******************************************************************************************
			m_ConPC.SetWindowText(_T("断开服务器"));
			m_buttonSend.EnableWindow(TRUE);
			m_buttonShowHistory.EnableWindow(TRUE);
			UpdateData(false);
		}		
	}
}

发送消息

void UDPClientDlg::OnBnClickedSendmsg()
{
	CString  msg;
	//获得消息框里的字符串
	GetDlgItemText(IDC_EDIT_MSG, msg);
	int selectIndex = m_userslist.GetCurSel();
	if(selectIndex == -1)
	{
		MessageBox(_T("请在聊天室中选择发送对象!"));
		return ;
	}
	if(msg == _T(""))
	{
		MessageBox(_T("请输入要发送的消息内容!"));
		return ;
	}
	CString usermsg;
	m_userslist.GetText(selectIndex, usermsg);
	if (usermsg == "所有人")
	{
		usermsg = _T("MEVERY") + msg;
	}
	else
	{
		usermsg = _T("M") + usermsg + _T(" ") + msg;
	}
	if (!usermsg.IsEmpty())
	{
		UpdateData(true);
		GetDlgItemText(IDC_EDIT_MSG, m_DataSend);
		if (m_DataSend != "")
		{
			int n = 0;
			m_DataSend = usermsg;
			//通过将宽字节转换成多字节来获得多字节的位数
			n = WideCharToMultiByte(CP_OEMCP, 0, m_DataSend, -1, NULL, 0, 0, FALSE);
			char* pBuff = new char[n];
			//初始化数组
			memset(pBuff, 0, n);
			//将宽字节转换成多字节
			WideCharToMultiByte(CP_OEMCP, 0, m_DataSend.GetBuffer(0), n, pBuff, n, 0, FALSE);
			//发送消息
			m_pClientSock->SendTo(
				(LPCTSTR)m_DataSend,
				m_DataSend.GetLength()*8,
				m_ServerAddr.uiPort,
				m_ServerAddr.strIPAddr);
			delete[] pBuff;
		}
	}
}

接受消息

void UDPClientDlg::ReceiveText()
{
	TCHAR buff[4096];  //定义接受数据的缓冲区
	int nRead;
	SocketAddr  sendClientAddr;
	nRead = m_pClientSock -> ReceiveFrom(buff,4096,sendClientAddr.strIPAddr,sendClientAddr.uiPort);
	if(nRead == SOCKET_ERROR){
	    return;
	}
	buff[nRead]  =  _T('\0');  //设置结束标志
	CString str(buff);
	//如果服务器通知更新聊天室列表
	if (-1 != strUpdate(str))
	{
		((UDPClientDlg *)AfxGetMainWnd())->UpdateUsers(str, strUpdate(str));
	}
	//否则就更新聊天窗口内容
	else
	{			
		//向聊天窗口添加接受到的信息
		CStringW  strTemp(buff);
		CStringW chartMsg;
		this->GetDlgItemTextW(IDC_EDIT_RECIEVEMSG,chartMsg);
		chartMsg += strTemp + _T("\r\n");
		this->SetDlgItemTextW(IDC_EDIT_RECIEVEMSG,chartMsg);
	}
}

运行结果

TCP协议运行结果
在这里插入图片描述
UDP运行结果
在这里插入图片描述
数据库数据截图
在这里插入图片描述
在这里插入图片描述

总结

第一次写博文,难免有错误之处,忘批评指正。本文TCP协议部分代码借鉴了MFC小程序 简易网络聊天室 博文,共同学习进步。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页