Кодим сокеты на MFC

cuttah (cutter@real.xakep.ru)

Xakep, номер #061, стр. 061-090-3


CServerSocket::CServerSocket(CxoDlg* pDlg)

{

m_pDlg = pDlg;

}

Все. Этой строкой мы связали наш серверный сокет с диалоговым окном. Осталось только добавить событие для входящих соединений. Для этого пропиши в метод OnAccept такой вот код:

void CServerSocket::OnAccept(int nErrorCode)

{

// TODO: Add your specialized code here and/or call the base class

CSocket::OnAccept(nErrorCode);

m_pDlg->NewConnect();

}

Теперь при новом соединении вызовется метод OnAccept. В нем произойдет согласие на входящий коннект, после чего при помощи m_pDlg->NewConnect(); управление передастся диалоговому окну.

После создания серверного сокета перейдем к реализации клиентской части. Для начала создавай новый класс CClientSocket на основе того же CSocket. В хедерниках нового класса добавь объявление класса СxoDlg. Далее измени конструктор класса. Поменяй пустой CClientSocket(); на CClientSocket(CxoDlg* pDlg);. А в .cpp файле пропиши следующие строки:

CClientSocket::CClientSocket(CxoDlg* pDlg)

{

m_pDlg = pDlg;

}

Здесь, как и в случае с CServerSocket, при создании нового объекта будет передаваться ссылка на диалоговое окно (в моем случае это класс CxoDlg).

Передача данных

Наше приложение может выступать как в роли сервера, так и в роли клиента. Серверная часть запускается по нажатию клавиши Create server. После ее клика выполняется событие OnBnClickedCreate, где создается серверный сокет. Вот как выглядит этот код:

void CxoDlg::OnBnClickedCreate()

{

// TODO: Add your control notification handler code here

m_pSocket = new CServerSocket(this);

m_pSocket->Create(m_port);

m_pSocket->Listen();

}

В m_port, как нетрудно догадаться, хранится значение порта. По умолчанию это порт 2345. Само значение m_port прописано как константа. Так что, если ты захочешь сделать этот параметр динамичным, то добавь на форме еще одно поле Edit и свяжи его с этой переменной (только не забудь убрать с нее статус константы).

Далее, если произойдет соединение, то вызовется метод NewConnect, в котором прописаны некоторые начальные данные для новой партии в крестики-нолики:

void CxoDlg::NewConnect(void)

{

pSocket = new CClientSocket(this);

m_pSocket->Accept(*pSocket);

m_type = 1;

m_turn = 1;

m_connected = 1;

}

В переменной m_type прописывается тип игрока. Т.е. чем он будет играть – крестиками или ноликами. Один обозначает, что это крестик, двойка – нолик. В m_turn отображается состояние хода. Если это 1, то ход твой, 0 – противника. Соответственно, с каждым ходом это значение будет заменяться противоположным.

Теперь о запуске клиентской части. При нажатии батона Connect запускается метод OnBnClickedButtonConnect. В нем происходит обновление данных в форме при помощи UpdateData (true);. Далее объявляется динамический объект pSocket класса CClientSocket, после чего происходит соединение. Если все прошло успешно, т.е. соединение установлено, то в переменные m_type и m_turn помещаются следующие значения:

if (pSocket->Connect(m_sAdr, m_port))

{

m_type=2;

m_turn=0;

m_connected=1;

Назад на стр. 061-090-2  Содержание  Вперед на стр. 061-090-4