聊天软件项目开发1

目录

1.1客户端/服务端界面设计

客户端 

服务端 

1.2IP和端口获取  

客户端

服务端

1.3重写socket,连接服务端与客户端 

客户端

服务端

1.4客户端与服务端互发消息

客户端 

服务端


1.1客户端/服务端界面设计

客户端 

利用亿图图示,画出要实现的客户端界面样式

在强大的艺术细胞加持下😊,我们的聊天软件界面也有了雏形!

 客户端MFC布局

编译结果

服务端 

服务端MFC布局

编译结果

1.2IP和端口获取  

客户端

获取IP和端口 

#include<atlbase.h>

void CMFCChatClientDlg::OnBnClickedConnectBtn()
{
	CString strPort, strIP;
	//获取控件里面内容
	GetDlgItem(IDC_PORT_EDIT)->GetWindowText(strPort);
	GetDlgItem(IDC_IPADDRESS)->GetWindowText(strIP);
	//CString 转char*
	USES_CONVERSION;
	LPCSTR szPort = (LPCSTR)T2A(strPort);
	LPCSTR szIP = (LPCSTR)T2A(strIP);
	TRACE("szPort=%s,szIP=%s", szPort, szIP);
}

服务端

获取端口

#include<atlbase.h>

void CMFCChartServerDlg::OnBnClickedStartBtn()
{
	TRACE("OnBnClickedStartBtn");
	CString strPort;
	//获取控件里面内容
	GetDlgItem(IDC_PORT_EDIT)->GetWindowText(strPort);
	//CString 转char*
	USES_CONVERSION;
	LPCSTR szPort = (LPCSTR)T2A(strPort);
	TRACE("szPort=%s", szPort);
}

1.3重写socket,连接服务端与客户端 

 最终效果

客户端

获取IP和端口,创建Socket (重写OnConnect和OnReceive),调用Connect连接

服务端

获取端口,创建Socket(重写OnAccept),开始监听;每次与客户端连接后再创建一个Socket(重写OnReceive)

客户端

继承CAsyncSocket类,并重写OnConnect( )和onReceive  

#pragma once
#include<afxsock.h>
class CMySocket :
    public CAsyncSocket
{
public:
    CMySocket();
    virtual ~CMySocket();
    //重写Connect函数
    virtual void OnConnect(int nErrorCode);
    //重写Receive函数
    virtual void onReceive(int nErrorCode);

};

重写函数实现 

void CMySocket::OnConnect(int nErrorCode)
{
	TRACE("############OnConnect");
	//获取主窗口
	CMFCChatClientDlg* dlg = (CMFCChatClientDlg*)AfxGetApp()->GetMainWnd();
	CString str;
	//获取系统当前时间
	dlg->m_tm = CTime::GetCurrentTime();
	//死背吧
	str = dlg->m_tm.Format("%X");
	str += _T("与服务器连接成功");
	//将时间在历史消息中显示
	dlg->m_list.AddString(str);
	//标准写法
	CAsyncSocket::OnConnect(nErrorCode);
}

void CMySocket::OnReceive(int nErrorCode)
{
	TRACE("############onReceive");
}

在客户端“连接”控件函数里 

获取端口和IP,创建一个Socket对象,创建一个Socket,然后进行连接

void CMFCChatClientDlg::OnBnClickedConnectBtn()
{
	//拿到端口和IP
	CString strPort, strIP;
	//获取控件里面内容
	GetDlgItem(IDC_PORT_EDIT)->GetWindowText(strPort);
	GetDlgItem(IDC_IPADDRESS)->GetWindowText(strIP);
	//CString 转char*
	USES_CONVERSION;
	LPCSTR szPort = (LPCSTR)T2A(strPort);
	LPCSTR szIP = (LPCSTR)T2A(strIP);
	TRACE("szPort=%s,szIP=%s", szPort, szIP);
	//字符串转数字
	int iPort = _ttoi(strPort);
	//创建一个socket对象
	m_client = new CMySocket;
	//创建套接字
	if (!m_client->Create()) {
		//错误代码10093,需要在项目.cpp文件的InitInstance( )函数里调用AfcSocketInit()函数初始话
		TRACE("m_client Create error %d", GetLastError());
		return;
	}
	else {
		TRACE("m_client Creat Success");
	}


	//连接
	/*判断是否连接成功在这里是没办法判断,需要在回调函数中判断;因此如果使用
	* if(!m_client->Connect(strIP,iPort))判断是否连接成功则会报出10035(WSAEWOULDBLOCK)错误
	* 在这里如果想判断的话就只需要判断是否等于SOCKET_ERROR就可以了
	*/
	if (m_client->Connect(strIP, iPort) != SOCKET_ERROR) {
		TRACE("m_client Connect errot %d", GetLastError());
	}


}

服务端

CServerSocket继承CAsyncSocket类,并重写OnAccept( )函数 ——监听类

#pragma once
#include<afxsock.h>
class CServerSocket :
    public CAsyncSocket
{
public:
    CServerSocket();
    virtual ~CServerSocket();
    virtual void OnAccept(int nErrorCode);
};

重写函数实现

void CServerSocket::OnAccept(int nErrorCode)
{
	TRACE("#####OnAccept");
	CMFCChartServerDlg* dlg = (CMFCChartServerDlg*)AfxGetApp()->GetMainWnd();
	//每次相连创建一个连接socket
	dlg->m_chat = new CChatSocket;
	//接收客户端连接
	Accept(*(dlg->m_chat));
	CString str;
	dlg->m_tm = CTime::GetCurrentTime();
	str = dlg->m_tm.Format("%X");
	str += _T("客户端连接成功");
	dlg->m_list.AddString(str);
	dlg->m_list.UpdateData(FALSE);
	CAsyncSocket::OnAccept(nErrorCode);
}

 CChatServet继承CAsyncSocket类,并重写OnReceive( )函数 ——连接类

#pragma once
#include <afxsock.h>
class CChatSocket :
    public CAsyncSocket
{
public:
    CChatSocket();
    virtual ~CChatSocket();
    virtual void OnReceive(int nErrorCode);

};

 重写函数实现

void CChatSocket::OnReceive(int nErrorCode)
{
}

在服务端“启动”控件函数里   

获取端口值,创建Socket对象,创建Socket,监听

void CMFCChartServerDlg::OnBnClickedStartBtn()
{
	TRACE("OnBnClickedStartBtn");
	CString strPort;
	//获取控件里面内容
	GetDlgItem(IDC_PORT_EDIT)->GetWindowText(strPort);
	//CString 转char*
	USES_CONVERSION;
	LPCSTR szPort = (LPCSTR)T2A(strPort);
	TRACE("szPort=%s", szPort);
	//创建服务器Socket的对象
	m_server = new CServerSocket;
	//创建Socket(套接字)
	int iPort = _ttoi(strPort);

	if (!m_server->Create(iPort)) {
		TRACE("m_server Create errorCode=%d", GetLastError());
		return;
	}

	//监听,当有客户端连接时回调OnAccept
	if (!m_server->Listen()) {
		TRACE("m_sercer listen Create errorCode=%d", GetLastError());
		return;
	}
	CString str;
	m_tm = CTime::GetCurrentTime();
	str = m_tm.Format("%X");
	str += _T("建立服务");
	m_list.AddString(str);
	//进行数据更新,FALSE把数据从控件搞下来,TRUE把数据从控件搞上去
	UpdateData(FALSE);
}

1.4客户端与服务端互发消息

最终效果

服务端(客户端)

在控件函数中

发送:获取编辑框内容→调用send函数发送→在历史消息框显示信息内容→清空编辑框

在OnReceive函数中

接收:使用Receive函数获得服务端(客户端)发送内容→显示在消息列表框

客户端 

发送控件函数

void CMFCChatClientDlg::OnBnClickedSendBtn()
{
	TRACE("Client SEND MESG");
	//1.获取编辑框内容
	CString strTmpMsg;
	GetDlgItem(IDC_SENDMSG_EDIT)->GetWindowText(strTmpMsg);

	//转char*类型
	USES_CONVERSION;
	char* szSendBuf = T2A(strTmpMsg);
	//2.发送给服务端,SEND_MAX_BUF(1024)是一个宏定义 ,在头文件MFCChartClient.h文件中
	m_client->Send(szSendBuf, SEND_MAX_BUF, 0);
	//3.显示到列表框里
	CString strShow;
	CString strInfo = _T("我:");
	strShow = CatShowString(strInfo, strTmpMsg);
	m_list.AddString(strShow);
	//控件更新
	UpdateData(FALSE);

	//清空编辑框
	GetDlgItem(IDC_SENDMSG_EDIT)->SetWindowText(_T(""));
	// TODO: 在此添加控件通知处理程序代码
}

//拼接显示信息 时间+呢称+消息
CString CMFCChatClientDlg::CatShowString(CString strInfo, CString strMsg)
{
	//时间+呢称+消息
	CString strTime;
	CTime tmNow;
	tmNow = CTime::GetCurrentTime();
	strTime = tmNow.Format("%X");
	CString strShow;
	strShow = strTime;
	strShow += strInfo;
	strShow += strMsg;
	return strShow;
}

 OnReceive函数里

void CMySocket::OnReceive(int nErrorCode)
{
	//获取服务端发送内容
	TRACE("############onReceive");
	CMFCChatClientDlg* dlg = (CMFCChatClientDlg * )AfxGetApp()->GetMainWnd();
	//SEND_MAX_BUF(1024)是一个宏定义 ,在头文件MFCChartClient.h文件中
	char szRecvBuf[SEND_MAX_BUF] = { 0 };
	Receive(szRecvBuf, SEND_MAX_BUF, 0);
	TRACE("###########szRecvBuf=%s", szRecvBuf);

	//显示在列表框
	USES_CONVERSION;
	CString sreRecvMsg = A2W(szRecvBuf);
	CString strInfo = _T("服务端:");
	CString strShow;
	strShow = dlg->CatShowString(strInfo, sreRecvMsg);
	dlg->m_list.AddString(strShow);
	CAsyncSocket::OnReceive(nErrorCode);
}

服务端

 发送控件函数

void CMFCChartServerDlg::OnBnClickedSendBtn()
{
	// TODO: 在此添加控件通知处理程序代码
	TRACE("###### Server Send Msg");
	//获取编辑框内容
	CString strTmpMsg;
	GetDlgItem(IDC_SEND_EDIT)->GetWindowText(strTmpMsg);
	//转char*类型
	USES_CONVERSION;
	char*szSendBuf = T2A(strTmpMsg);

	//MAX_SERVER_BUF(1024)是一个宏定义 ,在头文件MFCChartServer.h文件中
	m_chat->Send(szSendBuf, MAX_SERVER_BUF, 0);
	//3.显示到列表框里
	CString strInfo = _T("我:");
	CString strShow;
	strShow = CatShowString(strInfo, strTmpMsg);
	m_list.AddString(strShow);
	//控件更新
	UpdateData(FALSE);

	//清空编辑框
	GetDlgItem(IDC_SEND_EDIT)->SetWindowText(_T(""));
	// TODO: 在此添加控件通知处理程序代码
}

//拼接显示信息 时间+呢称+消息
CString CMFCChartServerDlg::CatShowString(CString strInfo, CString strMsg)
{
	//时间+呢称+消息
	CString strTime;
	CTime tmNow;
	tmNow = CTime::GetCurrentTime();
	strTime = tmNow.Format("%X");
	CString strShow;
	strShow = strTime;
	strShow += strInfo;
	strShow += strMsg;
	return strShow;
}

OnReceive函数

void CChatSocket::OnReceive(int nErrorCode)
{
	//获取客户端发送内容
	TRACE("#####Server OnReceive");
	CMFCChartServerDlg* dlg = (CMFCChartServerDlg*)AfxGetApp()->GetMainWnd();
	//MAX_SERVER_BUF(1024)是一个宏定义 ,在头文件MFCChartServer.h文件中
	char szRecvBuf[MAX_SERVER_BUF] = {0 };
	//便准写法
	Receive(szRecvBuf, MAX_SERVER_BUF, 0);

	TRACE("############sERVER szRecvBuf=%s", szRecvBuf);
	//2.显示buf
	USES_CONVERSION;
	CString sreRecvMsg = A2W(szRecvBuf);
	CString strInfo = _T("客户端:");
	CString strShow;
	strShow = dlg->CatShowString(strInfo, sreRecvMsg);
	dlg->m_list.AddString(strShow);
	CAsyncSocket::OnReceive(nErrorCode);

}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值