c++/MFC CSocket仿QQ聊天软件,实现1对1聊天,群聊


学习,c++有2个星期了。本来,本人是做php出身的。做php快2年了,最近身边多了很多高手。让自己对c开始感兴趣了,就开始学习c++了。首先接触的就是mfc。前几天,看到了一个博文,是有关,mfc网络编程的。可对方,的实例只能是多对多,出于兴趣,自己改写了下它的程序,实现了点对点的聊天。所以,本实例并非纯原创的。这个还请大家见谅,尤其是作者。我在他程序基础上,增加了1对1的聊天,同时还保留了群聊。而且,最关键的是,我增加了很多备注。很适合新手学习。。。本人也是新手,还请各位高手提出宝贵建议。。。先谢谢大家了。

如果要转载请注明原地址:http://blog.csdn.net/open520yin/article/details/8222279

实例下载地址:http://download.csdn.net/detail/open520yin/4808903(为了自己能有点下载积分,客户端和服务端一起打包5个积分不算贵吧。。呵呵。。。)


大家要是想看懂这个可能还需要先了解一下mfc的socket的一些基本使用规则我也有一篇博文写了

c++/MFC 极为简单的socket实例:http://blog.csdn.net/open520yin/article/details/8202465

MFC的CSocket编程,利用CSocket实现一个基于TCP实现一个QQ聊天程序。

/  服务端 start  ///

先讲讲服务端,一切先从服务端开始:
首先就是要使用AfxSocketInit初始化winsocket,

//初始化winSock库,成功则返回非0否则返回0
	WSAData wsData;
	if(!AfxSocketInit(&wsData))
	{
		AfxMessageBox(_T("Socket 库初始化出错!"));
		return false; 
	}

m_iSocket 是一个 CServerSocket*的 指针  ,CServerSocket类是一个我们自己的类我会在后面给出相应代码,他继承于CSocket类。

//创建服务器端Socket、采用TCP
	m_iSocket = new CServerSocket();
	if(!m_iSocket)
	{
		AfxMessageBox(_T("动态创建服务器套接字出错!"));
		return false;
	}

实例socket好了,就要创建套接字了。。这里的端口要和客户端连接的端口一致,不然就连接不上。而且,这个端口,要和服务器的其他软件端口不能冲突,怎么去判断冲突,可以自己谷歌一下,很简单的。我这里就直接写死了,这个端口一般不会被占用的。。

        //端口使用8989
	if(!m_iSocket->Create(8989))
	{
		AfxMessageBox(_T("创建套接字错误!"));
		m_iSocket->Close();
		return false;
	}

创建好了就要,开始监听这个端口了。这个是一般的,socket必须建立的几个过程。。

    if(!m_iSocket->Listen())
    {
        AfxMessageBox(_T("监听失败!"));
        m_iSocket->Close();
        return false;
    }

走完上面的几个步骤,这样,服务端,就能和客户端接受和发送消息了。大家可能会很奇怪,上面那个怎么没有绑定端口,直接listen了。。。这个我那个简单socket里有介绍,因为,Create 方法已经包含了 Bind 方法,如果是以 Create 方法创建socket的前提下不能再调用 Bind ,要不一定出错。

然后重载ExitInstance,退出时对进行清理

    int CNetChatServerApp::ExitInstance()  
    {  
    if(m_iSocket)  
    {  
    delete m_iSocket;  
    m_iSocket = NULL;  
    }  
    return CWinApp::ExitInstance();  
    }  


我再去看看上面用到的CServerSocket类,这个是用来,服务端接收消息用的。开启了监听这里的OnAccept()方法就会一直被循环调用。这个方法其实是重写CSocket类的OnAccept()方法。只要socket开启了监听,OnAccept就会被循环调用,我那个简单的socket实例,是开启一个while进行死循环来达到这个目的。大家不要介意,我也是新手。这里OnAccept方法为什么能一直被循环执行,我到现在也没弄明白,如果有高手知道请告诉我下。但是我知道,这里就是如果服务器有收到消息就会调用这里,提示ClientSocket接受消息。

void CServerSocket::OnAccept(int nErrorCode)
{
	//接受到一个连接请求
	CClientSocket* theClientSock(0);
        //初始化在初始化里把m_listSockets赋值到m_pList里
        theClientSock = new CClientSocket(&m_listSockets);
	if(!theClientSock)
	{
		AfxMessageBox(_T("内存不足,客户连接服务器失败!"));
		return;
	}
	Accept(*theClientSock); //接受
	//加入list中便于管理,这个很关键
	m_listSockets.AddTail(theClientSock);
	CSocket::OnAccept(nErrorCode);
}
OnAccept收到消息,就会实例CClientSocket类,这里其实主要是,服务端发送消息和接受消息的主要部分。也是服务端,最核心的部分。OnAccept收到消息后,就会通知CClientSocket来接受消息。注意了,CserverSocket是接收消息而CClientSocket是接收消息。接收,接受还是有区别的。这个关系我们要理解清楚。这个是我自己的理解,不时候是否有错误。还请高手赐教。。我学c++最多不过半个月,有些东西,都真是靠自己的理解。下面的接受消息OnReceive方法怎么调用的,我也有点模糊,这个方法好像是重写Socket的。就有数据来,他就会自动调用。m_listSockets.AddTail(theClientSock);这个很关键,m_listSockets是CPtrList类型,我对这个也还不太了解,经过我一些认识,这个是存放socket连接,成功一个就会加入这个,是一个链表。用来存放所有连接到服务器的socket连接的,这个后面会经常用到。

下面的HEADER是一个结构体,定义如下

typedef struct tagHeader{
	int type ;//协议类型
	int nContentLen; //将要发送内容的长度
	char to_user[20];
	char from_user[20];
}HEADER ,*LPHEADER;
这个结构体,要和客户端保持一致,不然我担心会有问题。就算没有问题,我估计转换也麻烦。尽量保持一直吧,这个也算是一种协议吧。客户端传输的时候,也传递这样的结构体。下面的方法,具体就看看备注吧。我在备注里讲解了
  • 26
    点赞
  • 123
    收藏
    觉得还不错? 一键收藏
  • 41
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值