Урок 60 Простенький сетевой чат TClientSocket & TServerSocket
6 марта 2007
В колонках играет: Spor - Lose it
TClientSocket & TServerSocket
Чтобы лучше разобраться в работе этих компонентов я предлагаю написать простенький сетевой чат, на примере которого можно будет легко увидеть компоненты в действии.
Для начала создадим новый проект(File->New->Application), поместим на форму компоненты: TClientSocket и TServerSocket c (закладки Internet) чтобы наша программа могла быть и клиентом и сервером (не одновременно конечно :D
Далее разместим компонент TMemo c (закладки Standart) - в нем как вы догадались будет отображаться текст чата.
Следующим на форму нужно кинуть компонент TEdit (закладки Standart) - в него мы будем писать текcт, который нужно отправить собеседнику.
Кидаем на форму TButton . Кроме того что уже есть на форме, нам еще понадобится три кнопки и два эдита (TEdit) (их назначение описывается по ходу обращения к ним) .
Итак, на форме :
~ClientSocket1 и ServerSocket1
~Memo1
~3 Edit
~4 button
Теперь изменяем свойства:
~Button1->Caption на "Отправить"
~Button2->Caption на "Создать"
~Button3->Caption на "Соединиться"
~Button4->Caption на "Отключить" .
Убираем текст во всех Эдитах . Свойство Memo1->ReadOnly = true , ClientSocket1->Host - нужно написать IP-адрес сервера к которому вы будете присоеденяться.
(IP-адресс устанавливается в настройках соединения Windows), если прописать 127.0.0.1 , то вы будете конектиться к себе на компьютер (так удобно делать, когда проверяешь на работоспособность свою программу. Запустив ее дважды, одна клиент с 127.0.0.1 , а другая сервер !) если же вы коннектитесь к другу, то заранее договоритесь какой будет Ай-Пи-адрес (143.0.0.5 - например). Но для того чтобы Ай-Пи -адресс можно было легко сменить, мы и положили на форму один из Эдитов, его текст при коннекте и будет отвечать свойству
ClientSocket1-> Address=Edit3->Text;
В свойстве ClientSocket1->Port и ServertSocket1->Port - должны стоять одинаковые значения, чтобы Сервер и Клиент прослушивали и работали на один порт . Число можно выбрать любое (1024 например).
Кнопку "Отключиться" изначально нужно сделать недоступной(Button4->Enabled = false) так как вначале отсоеденяться нам нет от кого .
Дальше опишем обработчики событий для кнопок "Создать", "Соединиться", "Отключить" .
Кнопка "Создать" - активизирует сервер. Он начинает прослушивать порт на коннект со стороны клиента .
void __fastcall TForm1::Button2Click(TObject *Sender)
{
ServerSocket1->Active= true;
// Делаем недоступную "Соединиться" (так как мы уже сервер)
Button3->Enabled= false;
// Делаем доступную "Отключиться" (понятно зачем)
Button4->Enabled= true;
Memo1->Lines->Add("Сервер создан");
}
Так наша программа стала сервером !
Давайте опишем клиента!(Кнопка "Соединиться")
В Edit3->Text впишите 127.0.0.1 - предполагается что тестироваться будет на одном компьютере (чтоб других не заморачивать:)
void __fastcall TForm1::Button3Click(TObject *Sender)
{
ClientSocket1->Host=Edit3->Text;
ClientSocket1->Address=Edit3->Text;
ClientSocket1->Active= true; // Делаем недоступную "Создать" (так как мы коннектимся)
Button2->Enabled= false; // Делаем доступную "Отключиться" (понятно зачем)
Button4->Enabled= true;
}
Дальше будем описывать свойства компонентов Клиента и Сервера OnConnect (когда присоединился) .
void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Клиент присоединился");
}
Это когда вы сервер и к Вам присоединились, на Мемо появится надпись !
Для клиента почти тоже самое :
void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Вы присоединены");
}
Отлично , дальше остается только рассказать Вам зачем Edit2 на форме и описать кнопку "Отправить" .
Итак, Эдит2 нам нужен для Вашего ника ! Ведь какой чат без ника !
Теперь самое главное - описание кнопки "Отправить :
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(Edit2->Text == "")
{
ShowMessage("Введите Ваш ник !");
return ;
}
if(Edit1->Text == "")
{
ShowMessage("Введите текст который надо отправить");
return ;
}
//Это была обработка исключительных ситуаций , типа пустых строк ввода ;
Memo1->Lines->Add(Edit2->Text+":: "+ Edit1->Text) ;
if (ServerSocket1->Active == true) {ServerSocket1->Socket->Connections[0]->SendText(Edit2->Text+"::"+Edit1->Text);
}
else
{
ClientSocket1->Socket->SendText(Edit2->Text+"::"+Edit1->Text);}
Edit1->Text = "" ;
}
Теперь разберемся с этой кучей кода :
//добавляем свое сообщение себе в Мемо
Memo1->Lines->Add(Edit2->Text+":: "+ Edit1->Text) ;
if (ServerSocket1->Active == true){ServerSocket1->Socket->
Connections[0]->SendText(Edit2->Text+"::"+Edit1->Text)};
Если мы сервер, то посылаем нашу строку первому в списке клиенту ( чат розщитан на двоих ) , иначе :
else {
ClientSocket1->Socket->SendText(Edit2->Text+"::"+Edit1->Text);
}
Посылаем строку серверу !
Независимо от того кто мы (клиент-сервер)
Очищаем Эдит1 : Edit1->Text = "" ;
Также надо описать прием информации и занесение ее в Мемо1. Делается это обработчиком события OnRead у TClientSocket и TserverSocket :
Клиент:
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add(Socket->ReceiveText()) ;
}
Сервер:
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add(Socket->ReceiveText()) ;
}
Вот вроди бы и все.