Розмістимо на діалоговому вікні одну кнопку з ідентифікатором IDC_LISTEN і заголовком Listen і один Edit з ідентифікатором IDC_DATA. При натисканні на кнопку Listen сервер почне слухати мережу. Після того, як клієнт приєднається до нашого сервера і відправить деякі дані, вони з'являться в нашому Edіt. Для простоти після з'єднання тільки клієнт зможе відправляти дані. Якщо ви захочете відправляти дані також і із сервера, то вам доведеться додати в серверну частину нашої програми код, аналогічний кодові клієнтської частини, яку ми розглянемо в розділі 3.2.
Після розміщення всіх елементів наша програма буде виглядати приблизно так:
Далі пунктом Add Variable контекстного меню елемента Edit припишемо цьому елементу змінну m_sData типу CEdit.
Приступимо безпосередньо до написання коду. Пунктом контекстного меню Add | Class на вкладці Class View створимо новий MFC клас CMySocket як нащадок класу CSocket.
Додамо в клас CMySocket (файл MySocket.h) змінну типу покажчик на CServDlg:
public:
CServDlg* m_pDlg; .
У цій змінній буде зберігатися покажчик на наше діалогове вікно. Оскільки ми тут використовуємо клас CServDlg, то необхідно додати рядок
class CServDlg;
безпосередньо перед оголошенням класу CMySocket.
Далі ми повинні додати метод для завдання значення змінній m_pDlg. Назвемо його SetParentDlg:
void SetParentDlg(CServDlg *pDlg);
Реалізація методу (файл MySocket.cpp) буде така
void CMySocket::SetParentDlg(CServDlg *pDlg)
{
m_pDlg=pDlg;
}
Тепер нам потрібно в нашому класі написати дві віртуальні функції – OnAccept і OnReceive з заголовками:
virtual void OnAccept (int nErrorCode) ;
virtual void OnReceive (int nErrorCode) ; .
Перша буде викликатися, коли наш сокет, який прослуховує мережу, одержить запит на з'єднання від клієнтської сторони. Друга – при одержанні даних від клієнта. Фунції додамо за допомогою пункту Add | Add function контекстного меню класу CMySocket на вкладці Class View.
В одержані заготовки для функцій додамо такий код:
void CMySocket::OnAccept (int nErrorCode)
{
AfxMessageBox("Есть соединение");
m_pDlg->OnAccept();
CSocket::OnAccept(nErrorCode);
}
void CMySocket::OnReceive(int nErrorCode)
{
AfxMessageBox("Данные получены");
m_pDlg->OnReceive();
CSocket::OnReceive(nErrorCode);
}
У цих двох фрагментах ми після показу МеssаgeBох викликаємо однойменні функції OnAccept() і OnReceive() нашого діалогового вікна. Виклик виконаємо за допомогою змінної m_pDlg, в якій і зберігається покажчик на головне вікно. Ці функції діалогового вікна у нас поки що не написані. Чому код з обробки краще писати у класі діалогового вікна, а не в класі сокета? Тому що дані, як правило, пересилаються саме діалоговому вікну для відображення і подальшої обробки, а не нашому сокету. Але обробку можна робити й у класі сокета. Оскільки ми в цьому фрагменті використовуємо змінну m_pDlg, то перед реалізацією методів у файлі MySocket.cpp пишемо рядок
#include "ServDlg.h" .
Тепер займемося класом діалогового вікна. Для початку в файлі ServDlg.h задамо дві змінні типу CMySocket:
#include "MySocket.h"
. . .
class CServerDlg : public CDialog
{
. . .
public:
CMySocket m_pListenSocket;
CMySocket m_pConnectSocket;
. . .
Як бачимо, сокетів у нас два. Перший (m_pListenSocket) прослуховує мережу. Коли серверна частина нашого додатка починає працювати, саме він приймає на заданому порту запит від клієнта. Як тільки від клієнта надійде запит, m_pListenSocket переведе з'єднання на сокет m_pConnectSocket, який буде займатися передачею даних, а сам буде продовжувати слухати далі.
У методі OnInitDialog за допомогою SetParentDlg задамо значення для змінної m_pDlg в сокетах:
BOOL CServDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_pListenSocket.SetParentDlg(this);
m_pConnectSocket.SetParentDlg(this);
m_pListenSocket.Create(2000); // 2000 порт
return TRUE;
}
У результаті змінна m_pDlg буде показувати на поточне діалогове вікно.
Далі додаємо методи OnAccept і OnReceive. Реалізація методів має вигляд
void CServDlg::OnAccept ()
{
m_pListenSocket.Accept(m_pConnectSocket);
}
void CServDlg::OnReceive ()
{
char *pBuf=new char[1025];
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.