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

cuttah (cutter@real.xakep.ru)

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


}

Это значит, что ты играешь ноликами, и первый ход не твой, а противника.

Примитивный протокол

Я специально взял очень примитивный протокол передачи данных, чтобы не перегружать его. И вот как он устроен. Когда кто-нибудь делает свой ход, неважно, крестики это или нолики, передаются 4 байта. В первых двух байтах находится числовое значение в ASCII кодах, показывающее расположение по оси X. В следующих двух байтах - по оси Y. Вот как выглядит код для передачи этой информации:

if (m_stat[pos_x][pos_y]==0)

{

m_turn=0;

/* Пропущена часть кода */

pSocket->Send(out, 4);

this->AddTarget(pos_x, pos_y, m_type);

}

В переменной out (тип CString) находятся эти самые 4 байта с информацией о координатах нового хода.

Теперь давай посмотрим, как же обрабатываются полученные данные о ходе. Когда приходит какой-то пакет, то вызывается метод OnReceive класса CClientSocket. И вот что там происходит:

void CClientSocket::OnReceive(int nErrorCode)

{

char pos[5];

char num[3];

int x, y;

CString data;

CSocket::OnReceive(nErrorCode);

this->Receive(pos, 4);

pos[4]='\0'; num[2]='\0';

num[0]=pos[0]; num[1]=pos[1];

x=atoi(num);

num[0]=pos[2]; num[1]=pos[3];

y=atoi(num);

m_pDlg->GetNewPos (x, y);

}

Здесь совершается обработка пакета. Информация о координатах помещается в две int переменные x и y. А потом эти данные передаются диалоговому окну при помощи метода GetNewPos. Так и происходит обмен пакетами между двумя игроками. Естественно, способ крайне примитивный, но зато наглядный. При этом ты всегда можешь поменять протокол. Доработать его, например, чтобы в нем была проверка на верность передачи координат.

Недоделки

Сейчас программа очень легко обманывается. Ты можешь просто прислать координату, где твой противник уже сделал ход, тем самым заменив его ход своим. Также отсутствует явный обмен о том, что партия закончилась. Это все проверяется только самой программой. К тому же не отображается информация, что клиент присоединился. О его коннекте можно узнать, только нервно покликав по полю, в надежде на то, что там появится твой крестик. Есть глюк и с созданием сервера. Ведь объявляется всего один объект на основе CServerSocket. Если нажать на кнопку Create server несколько раз, а потом сделать коннект к этому серверу, то программа просто упадет. Так что необходимо добавить слежку за состоянием объекта. Т.е. убивать сам объект и порождать его заново.

Гаматься

Собственно, мы это сделали :). Мы написали с тобой простенькое клиент-серверное приложение при помощи асинхронных сокетов. Но несмотря на всю простоту, ты получил весьма важные знания для дальнейшего изучения сетевого программирования под винды. В будущем я советую тебе разобраться с работой тредов, чтобы ты смог нормально разносить различные соединения по новым потокам. Это крайне полезная вещь. А сейчас предлагаю изучить полные исходные коды и добавить в них что-то свое. Удачи!

Интересная добавка к крестикам-ноликам – наличие бота. Т.е. возможность игры с искусственным интеллектом. Изначально я писал эту программу именно для игры с ботом, но сам бот получился несколько глючным. Он у меня иногда выигрывал, но это случалось уж слишком редко :). Так что попробуй написать своего. Если получится что-то занимательное, присылай полученный результат мне на почту. Мы обязательно выложим твое творение на наш сайт.

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