Работа с сокетами в Delphi

Сокеты (от socket (англ.) — разъём, гнездо) — это программный интерфейс, обеспечивающий процессы обмена информацией между процессами.

В этой статье рассказывается о том, как разрабатываются приложения на основе сокетов на Borland Delphi. Стоит обратить внимание на то, что сокеты – база для протоколов. Иными словами, с их помощью можно самостоятельно создать (имитировать) POP, FTP, HTTP или любой другой протокол – даже новый, свой собственный.

Принцип работы с сокетными протоколами

Одни из основных достоинств сокетного обмена информацией в сети можно назвать его гибкость. Главный принцип работы с сокетами состоит в отправке последовательности символов другому компьютеру, будь то сообщение или целый файл. Причём без «ручного» контроля правильности передачи (как во время работы с COM-портами).

Примерный алгоритм работы с сокетами Delphi

socket delphi

Определение свойств Port и Host. Для успешного соединения свойствам Port и Host компонента TClientSocket необходимо присвоить некоторые значения.

В свойстве Port нужно указать номер порта для подключения (1 – 65535, но лучше брать из диапозона 1001 – 65535, потому что номера до 1000 могут оказаться заняты системными службами).

Host — хост-имя или IP-адрес компьютера, с которым требуется соединиться. Например, rus.delphi.com или 192.128.0.0.

Открытие сокета. Будем рассматривать сокет как очередь символов, передающихся с одного компьютера на другой. Открыть сокет можно, вызвав метод Open (компонент TClientSocket) или присвоив значение True свойству Active. Тут нелишним будет поставить обработчик исключения на случай неудавшегося соединения.

Авторизация> подразумевает отправку серверу своего логина и пароля, однако сама схема авторизации зависит от сервера (если он не требует ввода этих данных, пункт можно пропустить).

Отправка/прием данных. Это как раз то, ради чего всё затеяно. От сервера зависит и то, через какой протокол производится обмена данными.

Закрытие сокета. По завершению обмена данными нужно закрыть сокет, вызвав метод Close компонента TClientSocket или присвоив значение False свойству Active.

Компонент TClientSocket

Столкнувшись с необходимостью работы с компонентом TClientSocket, разумным будет познакомиться с ним поближе.

Свойства:

Active (тип: Boolean) – показатель того, открыт или закрыт сокет. Открыт – значение True, закрыт – значение False. Доступно для записи.

Host (тип: string) – хост-имя компьютера, с которым нужно соединиться.

Address (тип: string) – тут IP-адрес компьютера, с которым нужно соединиться. В отличие от Host, здесь может быть указан только IP. Разница состоит в том, что если в Host указано буквенное имя компьютера, то IP запросится у DNS.

Port (тип: Integer (Word)) – номер порта компьютера, с которым нужно соединиться (1-65535).

Service (тип: string) – определяет службу, с портом которой произойдёт соединение (pop, ftp и т.д.). Можно сказать, что это некий справочник для сопоставления номера порта с каким-либо стандартным протоколом.

ClientType — содержит тип передачи данных:

ctBlocking — синхронная передача (OnRead и OnWrite не работают). Синхронный тип подключения подходит для поточного обмена данными;

ctNonBlocking — асинхронная передача (отправка/приём данных может производиться при помощи событий OnRead и OnWrite).

Методы:

Open — открывает сокет (присвоение свойству Active значения True).

Close — закрывает сокет (присвоение свойству Active значения False).

События:

OnConnect – возникает при установке подключения. В обработчике уже можно приступать к авторизации или отправке/приему данных.

OnConnecting – также возникает при подключении. Отличается от OnConnect тем, что подключение еще не установлено. Чаще всего используется, например, чтобы обновить статус.

OnDisconnect – событие возникает при закрытии сокета вашей программой, удаленным компьютером или из-за сбоя. OnError – событие возникает при ошибке. Во время открытия сокета это событие не поможет выловить ошибку. Во избежание появления сообщения от Windows об ошибке, лучше позаботиться о внутренней обработке исключений путём помещения операторов открытия в блок «try..except».

OnLookup – событие возникает при попытке получить IP-адрес от DNS.

OnRead – событие возникает при отправке вам каких-либо данных удалённым компьютером. При вызове OnRead возможна обработка принятых данных.

OnWrite – событие возникает, когда вашей программе разрешено писать данные в сокет.

Пример:


{В самом начале необходимо создать форму TForm1 и экземпляр Form1, создать на форме кнопку TButton, при нажатии на которую будет вызываться процедура Button1Click — обработчик события OnClick, и два поля TEdit, в которые предварительно нужно будет ввести хост-имя в один и порт в другой.
Обязательно нужно поместить компонент TClientSocket на форму!}

procedure Button1Click(Sender: TObject);
begin
  {В Host и Port пишем введённые в форме значения}
  ClientSocket1.Host := Edit1.Text;
  ClientSocket1.Port := StrToInt(Edit2.Text);
  {Открываем сокет и пытаемся подключиться}
  ClientSocket1.Open;
end;

procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
  {Если подключение прошло успешно, сокет закрываем, подключение обрываем}
  ClientSocket1.Close;
end;

Может показаться, что программа абсолютно бесполезна, т.к. не способна принести хоть какую-то пользу. На самом деле, она представляет собой простейший сканер портов, суть которого состоит в проверке готовности порта к приему/отправке данных.
Поняв принцип, по которому работают сокеты в целом, и разобравшись в этом элементарном примере, достаточно несложно понять, как отправить сообщение или файл удалённому компьютеру или авторизоваться на сервере. Стоит обратить внимание на то, что для пересылки по сети сложных структур и файлов понадобятся специальные операторы.

Например, некоторые методы TClientSocket.Socket (TCustomWinSocket, TClientWinSocket):

SendBuf(var Buf; Count: Integer) – отправка буфера через сокет. Это может быть любой тип: простой Integer, структура (record), или что-то ещё. Указать буфер нужно параметром Buf. Во втором параметре должен быть указан размер (в байтах) передаваемых данных (Count);

SendText(const S: string) – отправка текстовой строки;

SendStream(AStream: TStream) – отправка содержимого потока любого типа: файлового, из ОЗУ и т.д. Этот поток должен быть открыт.

В заключение

Из этой статьи можно почерпнуть знания, необходимые для поверхностного освоения понятия «сокеты» и приобретения общего понимания принципов работы с ними. Описание работы с сокетными потоками заслуживает отдельного внимания и выходит далеко за рамки этого повествования, так же, как и подробное описание процесса авторизации на сервере, блочной передачи файлов и различных нюансов использования сокетов.

. работа с сокетами делфи
. delphi работа с сокетами
Комментирование и размещение ссылок запрещено.