Исходные коды программ и игр

Программирование - работа и хобби

Исходный код чата по локальной сети

Язык программирования C++

Исходник сетевого чата

Программа для чата по локальной сети на С++С созданием локальной (домашней сети) открываются новые возможности общения сидя за компьютером. Несколько человек с помощью программы чата могут обмениваться сообщениями по сети.

Исходный код такого сетевого приложения прилагается ниже. Сетевая программа написана на языке С++ на базе библиотеки MFC. Для визуализации построения пользовательского интерфейса выбран тип приложения на основе диалоговых окон.

Количество подключаемых к чату клиентов не ограничивается. Для удобного хранения сокетов подключенных клиентов используется шаблонный класс стандартной библиотеки С++ class vector. Класс vector представляет собой динамический массив и поддерживает быстрый доступ к любому элементу.

Сокет для соединения по сети

Работу сетевого приложения чата обеспечивают сокеты. Сетевое соединение устанавливается посредством объектов класса CSock. Класс CSock произведен от высокоуровневого класса асинхронных сокетов CAsyncSocket. Асинхронная работа сокетов исключает блокировку пользовательского интерфейса во время установления соединения и отправки-получения сообщений по сети. Класс CAsyncSocket входит в состав богатейшей библиотеки MFC, облегчающей рутинный труд С++ программистов. CAsyncSocket - интуитивно понятная реализация в виде класса для низкоуровневого интерфейса Windows Sockets API. Дочерний класс CSock инкапсулирует в себе достоинства асинхронной работы с сокетами и небольшим дополнительным программным кодом обеспечивает полноценную сетевую работу чата.

Листинг реализации класса CSock:
// Событие подключения на стороне клиентского приложения.
void CSock::OnConnect(int nErrorCode)
{
    // Данные в родительское окно для индикации процесса соединения.
    CChatCppDlg* pDlg = (CChatCppDlg*)m_pParent;
    nErrorCode == 0 ? pDlg->OnConnect(FALSE) : pDlg->OnConnect(TRUE);
	
    CAsyncSocket::OnConnect(nErrorCode);
}

// Событие отключения от сети
void CSock::OnClose(int nErrorCode)
{
    Beep(2000, 300);
	
    CAsyncSocket::OnClose(nErrorCode);
}

// Событие получения сообщений.
void CSock::OnReceive(int nErrorCode)
{
    // Данные в родительское окно для визуальности приема сообщений.
    CChatCppDlg* pDlg = (CChatCppDlg*)m_pParent;
    pDlg->OnReceive();
	
    CAsyncSocket::OnReceive(nErrorCode);
}

// Запрос на подключение, направляемый клиентом серверу.
// Происходит на стороне серверного приложения.
void CSock::OnAccept(int nErrorCode)
{
    // Данные в родительское окно для индикации процесса соединения.
    CChatCppDlg* pDlg = (CChatCppDlg*)m_pParent;
    pDlg->OnAccept();

    CAsyncSocket::OnAccept(nErrorCode);
}

Подключение клиентов

При установлении сетевого соединения для каждого клиента создаётся отдельный сокет. Сокеты клиентов хранятся в динамическом массиве std::vector m_vecSockets. В момент акцептирования (принятия) клиентов в чате рассылается информация о количестве подключенных пользователей. Успешное подключение к сети индицирует заголовок приложения.

// Принимаем запросы на подключения
void CChatCppDlg::OnAccept(void)
{
    CSock* pSock = new CSock;
    pSock->m_pParent = this;

    // Если все в порядке добавим рабочий сокет в список 
    // подключенных рабочих сокетов.
    if(m_mainSocket.Accept(*pSock) == TRUE)
    {
        m_vecSockets.push_back(pSock);
        m_ButtonSend.EnableWindow(TRUE);
        SendCountPeople();

        SetWindowText("Сеть работает!");
    }
    else 
    {
        delete pSock;
    }
}

Сортировка сетевых сообщений

Поскольку сетевые сообщения могут содержать информацию любого типа (строки символов, числа, двоичные файлы) возникает необходимость создания сортировки сообщений внутри приложения. Исходник содержит один из способов сортировки типов сообщений. Для этого используется специальная структура для передачи по сети, содержащая в себе необходимые переменные.

Структура для передачи сетевых сообщений:
struct SENDBUFFER
{
    SENDBUFFER() 
    {
        typemessage = 0; 
        countpeople = 0;
        stopchat = false;
        ZeroMemory(name, sizeof(TCHAR)*14); 
        ZeroMemory(buffer, sizeof(TCHAR)*202);
    }

    int typemessage;
    int countpeople;
    bool stopchat;
    TCHAR name[14];
    TCHAR buffer[202];
};

Сортировку получаемых сообщений удобно производить с помощью оператора swicth:

m_mainSocket.Receive(&sb, sizeof(SENDBUFFER));

switch(sb.typemessage)
{
	case m_TypeMessage::tmCountPeople:
		{
			...
		}
		break;
	case m_TypeMessage::tmChat:
		{
			...
		}
		break;
	case m_TypeMessage::tmDisconnect:
		{
			...
		}
		break;
	default:
		AfxMessageBox("Неизвестное сообщение!");
		break;
}

Макросы WINVER и _WIN32_WINNT для разных версий

Исходный код приложения сетевого чата можно использовать в разных версиях Windows, как более ранних, так и в современных.

Для работы в ранних версиях операционной системы Windows требуется закомментировать отмеченные в листинге строки кода.

// Макросы для работы в ранних версиях операционной системы Windows
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER				// Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0400		// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif

#ifndef _WIN32_WINNT		// Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0400		// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif


/*
// Макросы для новых версий Windows
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0A00
*/

Для работы в новых версиях Windows требуется закомментировать макросы WINVER и _WIN32_WINNT для ранних версий.

/*
// Макросы для работы в ранних версиях операционной системы Windows
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER				// Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0400		// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif

#ifndef _WIN32_WINNT		// Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0400		// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif
*/


// Макросы для новых версий Windows
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0A00

Прикрепленный файл исходника чата по локальной сети

Доработав исходный код "под себя" можно изготовить полнофункциональное приложение для чата по сети, с возможностью отправки файлов, с шифрованием сообщений и т.д. Работа с MFC и языком программирования С++ в Visual Studio 2019 стала гораздо комфортней, чем в предыдущих версиях. Приятно отметить, что библиотека MFC не забыта и активно развивается.

Среда программирования MS Visual Studio 2019, обязательна установка MFC библиотеки версии 142 и выше.

Файл: chatcpp_vs16.zip
Размер: 62 Кбайт
Загрузки: 11184