网络编程(三)---- MFC 仿QQ聊天软件

本文介绍了如何使用MFC开发一个仿QQ聊天软件,包括服务器端和客户端的实现。重点讨论了WinSock库的初始化、端口检查、套接字创建与监听,以及自定义协议头的设计。在服务器端,通过CServerSocket类接收并响应客户端请求,客户端则通过CClientSocket类与服务器建立连接并发送消息。虽然当前仅实现了群聊功能,但为实现一对一聊天奠定了基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天来八一八,MFC的SOCKET 编程,利用CSocket实现一个基于TCP实现一个QQ聊天程序。你会发现,MFC要比WIN32 简单的多。但是如果你不理解具体API socket基础知识,你可能会觉得有一点费解。 所以在开始之前 我还是请大家先看看 http://blog.youkuaiyun.com/lh844386434/article/details/6664025    


在应用程序开始的时候,我们先应该初始话winSock 库,所以便会用到下面的一个函数。

BOOL AfxSocketInit( WSADATA* lpwsaData = NULL ); //用来初始化Socket,用WSAStartup();来初始化,在应用程序结束时他会自动调用WSACleanup()
我们在开始编程之前,应该调用这个函数,对Socket进行初始化。如果初始化成功返回非0 ,否则返回0.

可能人会问,这个函数加载的是那个版本的Socket库呢?通过查看底层代码,我们发现,他加载的是1.1版本的Socket

注意:这个函数只能在你自己应用程序的 CXXWinApp::InitInstance 中初始化.在初始化前还要记得加入头文件Afxsock.h

我服务器端程序 为  NetChatServer  所以我在的CNetChatServerApp::InitInstance()中加入

/CNetChatServerApp::InitInstance()///

   if(!AfxSocketInit())
	{
		AfxMessageBox(_T("Socket 库初始化出错!"));
		return false;
	}

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

   m_iSocket = new CServerSocket(); // 1.动态创建一个服务器Socket对象。
     if(!m_iSocket)
     {
	AfxMessageBox(_T("动态创建服务器套接字出错!"));
	return false;
     }

接着创建套接字

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

其中8989 是指定的端口号,但是要注意在保存我们指定的8989端口前,这个端口是空闲的没有被其他进程所占用,那怎么查看端口是否被其他进程占用呢?

首先打开cmd 键入 netstat -aon

 

你会看到所有的TCP/UDP 信息 ,但是由于太多了不好查看,所以。我们再在最下面 tasklist|find “8989”


现在我们看到 我们没有找到任何 和8989端口相关的东西,所以说明8989端口没有被占用。

创建了套接字以后按照win32的步骤我们就应该 对bind端口。

但是MFC 不这样,应为MFC的Create内部已经调用了bind ,如下是MFC的底层代码

BOOL CAsyncSocket::Create(UINT nSocketPort, int nSocketType,long lEvent, LPCTSTR lpszSocketAddress)
{
      if (Socket(nSocketType, lEvent))
      {
          if (Bind(nSocketPort,lpszSocketAddress))//调用了bind
                  return TRUE;
          int nResult = GetLastError();
          Close();
          WSASetLastError(nResult);
      }
      return FALSE;
}

所以 我们不用在调用bind 了,直接对套接字进行监听


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

/

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

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

//

下面 来看下CServerSocket的具体实现

#pragma once

#include "ClientSocket.h"

class CServerSocket : public CSocket
{
public:
	CServerSocket();
	virtual ~CServerSocket();
public : 
	CPtrList m_listSockets;//用来保存服务器与所有客户端连接成功后的ClientSocket


public : 
	virtual void OnAccept(int nErrorCode);
};

#include "stdafx.h"
#include "NetChatServer.h"
#include "ServerSocket.h"

CServerSocket::CServerSocket()
{

}

CServerSocket::~CServerSocket()
{

}

void CServe
评论 79
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值