Си++ или сетевое программирование

Так получилось, что мне нужно было написать за 2 дня приложение с интерфесом и хоть каким-то сетевым взаимодействием. Не для себя, но надо было. Но стояла одна проблема — я не знаю си++ :) Именно того где классы, процедуры и тд. Недолго думая обратился за помощью к гуглу, поставил по старой памяти борланд 6ой версии (да, я знаю, что он устарел, но это была единственная программа в которой я хотя бы знал куда тыкать) и через несколько часов курения манов по сетевому программированию я, совершенно не зная си++, написал простенький сетевой чат. Это не идеальный вариант, конечно же, но он работает, а для понимания TServerSocket и TClientSocket этого более чем достаточно.

Буду стараться писать в стиле мануалов.

Что же я делал:

Сначала был создан проект: File->New->Application

После этого на форму были добавлены следующие компоненты

Standart-Memo: Memo1 — здесь будет сам чат и всяческие сервисные сообщения

Standart-Button: всего я добавил 3 кнопки. Button1 - кнопка для создания сервера (чат может быть или сервером или чатом. Разделения я не делаю, так как это, я повторюсь, самый простой вариант чата для понимания принципа работы TServerSocket и TClientSocket), Button2 - кнопка для соединения с сервером и Button3 — кнопка «Отправить», благодаря которой мы можем отправлять то, что введем.

Standart-Edit: Edit1 — строка ввода данных. Здесь мы будем вводить то, что хотим отправить в чат. И Edit2 — IP адрес сервера, который по умолчанию будет равен вашему localhost'у (127.0.0.1).

В итоге мы получаем приблизительно такую форму, как указано на скриншоте:

Форма чата

Нравится? Тогда продолжим дальше. Мы нарисовали основные формы, теперь необходимо реализовать сервер и клиент. Для этого мы должны добавить следующие компоненты на форму:

Internet-ClientSocket и Internet-ServerSocket

Добавляем эти два компонента на форму и приступает к их программированию:

Назовем кнопку Button1 «Создать» задав соответсвующее свойство кнопки в панели Object Inspector.

Теперь запрограммируем кнопку на создание сервера:

void __fastcall TForm1::Button1Click (TObject *Sender)
{
ServerSocket1->Port = 127015 ; //зададим порт для прослушки
ServerSocket1->Active = true ; //активируем ServerSocket1
ServerSocket1->Open ();//запустим ServerSocket1
Button2->Enabled = false ;//делаем неактивной кнопку «Соединиться»
Memo1->Lines->Add («Сервер создан удачно. Ожидание участников.») ;
}

На этом мы закончили функцию создания сервера. Следующая функция необходима для работы клиента:
void __fastcall TForm1::Button2Click (TObject *Sender)
{
ClientSocket1->Host = Edit2->Text ;
ClientSocket1->Port = 127015 ;
ClientSocket1->Address = Edit2->Text; //задаем IP сервера из Edit1
ClientSocket1->Active = true ;
Button1->Enabled = false ;
}

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

Следующая функция необходима для чтения данных для клиента из сокета при его активности:

int connections; //глобальная переменная для всех функций. Кол-во текущих подключений.

void __fastcall TForm1::ServerSocket1Read (TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString txt;
txt = Socket->ReceiveText ();
connections = ServerSocket1->Socket->ActiveConnections;
for (int i=0;i<=connections-1;i++)
{
Memo1->Lines->Add («Client->»+txt);//печатаем то, что написал нам клиент
ServerSocket1->Socket->Connections[i]->SendText (txt);//отсылаем данные всем пользователям в чате.
}
}

И приблизительно такая же функция для клиента. Только на этот раз мы будем только считывать и печатать данные, так как мы клиент:

void __fastcall TForm1::ClientSocket1Read (TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add («Я->»+ClientSocket1->Socket->ReceiveText ()) ;
}

Следующие 2 функции обрабатывают события подключения клиента к серверу со стороны клиента и со стороны сервера:


void __fastcall TForm1::ServerSocket1ServerConnect (TObject *Sender,
TCustomWinSocket *Socket)
{
connections = ServerSocket1->Socket->ActiveConnections;
Memo1->Lines->Add («Клиент подсоединился. Активных подключений:»+connections);
}void __fastcall TForm1::ClientSocket1Connect (TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add («Вы присоединились к серверу. Приятного общения :)»);
}

Следующая функция будет выполнять отправку введенных в строка ввода данных. Обработаем это событие кнопкой Button3 и зададим ей свойство Caption «Отправить»:

void __fastcall TForm1::Button3Click (TObject *Sender) {
if (ClientSocket1->Active == true) {
ClientSocket1->Socket->SendText (Edit1->Text);//просто отправляем данные серверу
Edit1->Text = ""; //и очищаем строку ввода
}
}

Когда я писал эту статью я подразумевал, что вы знакомы с интерфейсом Borland C++ 6 и знаете, что каждое событие, которое не вызывается в какой либо из функций должно обрабатываться по событию. Для того, чтобы обработать события существует вкладка Events в меню Object Inspector. Вам необходимо соотнести все события клиента и сервера с соответствующими компонентами. В итоге должно получится что-то похожее:

LightChat v.0.1

4 комментария на “Си++ или сетевое программирование”

  1. А это какая архитектура? Все классы T{Его имя} откуда?

Пообсуждаем?