Слайд 2Протоколы
Каждая сеть должна следовать определенным правилам - протоколам при передачи
данных от одного компьютера к другому
В сети сам поток
информации представляется пакетами определенного размера. В частности каждый такой пакет содержит информацию: о своем размере, о том, где начало информации и какое место направления (т.е. кому в сети этот пакет предназначен). Устройства сети, которые получают такой пакет, смотрят по этим данным, куда его направить.
В зависимости от своего типа, одни устройства просто рассылают все пакеты по сети, это называется широковещательная рассылка, а некоторые очень детально изучают пакет и определяют точное его место направления, т. е. определяют маршрут следования пакета, или как еще говорят, маршрутизацию .
Слайд 3TCP/IP
Стек протоколовСтек протоколов TCP/IP — это два протокола нижнего уровня, являющиеся
основой связи в сети Интернет. Протокол TCP (Transmission Control Protocol)
разбивает передаваемую информацию на порции и нумерует все порции. С помощью протокола IP (Internet Protocol) все части передаются получателю. Далее с помощью протокола TCP проверяется, все ли части получены. При получении всех порций TCP располагает их в нужном порядке и собирает в единое целое.
Слайд 4TCP/IP
IP-adress - это уникальный сетевой адрес, идентифицирующий конкретный компьютер в
сети, в которой установлен протокол TCP/IP . IP-adress состоит из
четырех чисел, разделенных точками. Диапазон каждого из этих чисел, в общем случае лежит в пределах от 0 до 256 .
например, 125.115.125.48
Первые три числа определяют сеть, в которой находится компьютер, а последнее - компьютер в этой сети.
Слайд 5TCP/IP
Первые три числа (по-умному говорят - тетрады) определяют класс IP-адреса
. Таких классов три. Все эти сложности связанны именно с
тем, что протокол TCP/IP обеспечивает работу в глобальных сетях. Вы только представьте, сколько компьютеров входит в сеть Интернет!!! Ведь каждый из них пренадлежит какой-то своей локальной сети, которая входит в состав другой сети и так далее... И каждому нужно выделить уникальный адрес!!!
Итак, классы IP-adress
* Класс А - для больших организаций. Первое число от 0 - 126.
* Класс В - для средних организаций. Первое число от 128 - 191.
* Класс С - для небольших организаций. Первое число от 192 - 223.
Слайд 6HTTPHTTP (Hyper Text Transfer Protocol) — это протокол передачи гипертекста. Протокол
HTTP используется при пересылке Web-страниц с одного компьютера на другой.
FTP (File Transfer Protocol) — это протокол передачи файлов со специального файлового сервера на компьютер пользователя. FTP дает возможность абоненту обмениваться двоичными и текстовыми файлами с любым компьютером сети. Установив связь с удаленным компьютером, пользователь может скопировать файл с удаленного компьютера на свой или скопировать файл со своего компьютера на удаленный.
POP (Post Office Protocol) — это стандартный протокол почтового соединения. Серверы POP обрабатывают входящую почту, а протокол POP предназначен для обработки запросов на получение почты от клиентских почтовых программ.
SMTP (Simple Mail Transfer Protocol) — протокол, который задает набор правил для передачи почты. Сервер SMTP возвращает либо подтверждение о приеме, либо сообщение об ошибке, либо запрашивает дополнительную информацию.
uucp (Unix to Unix Copy Protocol) — это ныне устаревший, но все еще применяемый протокол передачи данных, в том числе для электронной почты. Этот протокол предполагает использование пакетного способа передачи информации, при котором сначала устанавливается соединение клиент-сервер и передается пакет данных, а затем автономно происходит его обработка, просмотр или подготовка писем.
telnet — это протокол удаленного доступа. TELNET дает возможность абоненту работать на любой ЭВМ сети Интернет, как на своей собственной, то есть запускать программы, менять режим работы и так далее. На практике возможности лимитируются тем уровнем доступа, который задан администратором удаленной машины.
DTN — протокол, предназначенный для обеспечения сверхдальней космической связи.
Слайд 7Сокеты
FTP, POP, SMTP, HTTP
сокеты - это база для этих
протоколов. Таким образом, пользуясь сокетами, можно самому создать (симитировать) и
FTP, и POP, и любой другой протокол, причем не обязательно уже созданный, а даже свой собственный
Слайд 8Определение св-в Host и Port - чтобы успешно установить соединение,
нужно присвоить свойствам Host и Port требуемые значения. Host -
это хост-имя (например: nitro.borland.com) либо IP-адрес (например: 192.168.0.88) компьютера, с которым надо соединиться. Port - номер порта (от 1 до 65535) для установления соединения. Обычно номера портов берутся, начиная с 1001 - т.к. номера меньше 1000 могут быть заняты системными службами (например, POP - 110).
Открытие сокета - после того, как Вы назначили свойствам Host и Port соответствующие значения, можно приступить непосредственно к открытию сокета (сокет здесь рассматривается как очередь, в которой содержатся символы, передающиеся от одного компьютера к другому).
Слайд 9Авторизация - этот пункт можно пропустить, если сервер не требует
ввода каких-либо логинов и/или паролей. На этом этапе Вы посылаете
серверу свой логин (имя пользователя) и пароль. Но механизм авторизации зависит уже от конкретного сервера;
Посылка/прием данных - это, собственно и есть то, для чего открывалось сокетное соединение. Протокол обмена данными также зависит от сервера;
Закрытие сокета - после всех выполненных операций необходимо закрыть сокет с помощью метода Close компонента TClientSocket (либо присвоить свойству Active значение False).
Слайд 10Описание свойств и методов компонента TClientSocket
Слайд 11Описание свойств и методов компонента TClientSocket
Слайд 12Пример
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;
Слайд 13В форму нужно поместить две кнопки TButton и три TEdit.
При нажатии на первую кнопку вызывается обработчик события OnClick -
Button1Click. Перед этим в первый из TEdit-ов нужно ввести хост-имя, а во второй - порт удаленного компьютера. После установления соединения можно посылать текстовые сообщения, вводя текст в третий TEdit и нажимая вторую кнопку TButton. Чтобы отсоединиться, нужно еще раз нажать первую TButton. Еще нужно добавить TListBox, в который будем помещать принятые и отправленные сообщения.
НЕ ЗАБУДЬТЕ ПОМЕСТИТЬ В ФОРМУ КОМПОНЕНТ TClientSocket!
Слайд 14procedure Button1Click(Sender: TObject);
begin
{Если соединение уже установлено - прерываем его.}
if ClientSocket1.Active
then begin
ClientSocket1.Close;
Exit; {...и выходим из обработчика}
end;
{Присваиваем свойствам Host и Port
нужные значения}
ClientSocket1.Host := Edit1.Text;
ClientSocket1.Port := StrToInt(Edit2.Text);
{Пытаемся открыть сокет и установить соединение}
ClientSocket1.Open;
end;
procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
{Как только произошло соединение - посылаем приветствие}
Socket.SendText('Hello!');
ListBox1.Items.Add('< Hello!');
end;
Слайд 15procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
{Если пришло сообщение - добавляем его
в ListBox}
ListBox1.Items.Add('> '+Socket.ReceiveText);
end;
procedure Button2Click(Sender: TObject);
begin
{Нажата кнопка - посылаем текст из
третьего TEdit}
ClientSocket1.Socket.SendText(Edit3.Text);
ListBox1.Items.Add('< '+Edit3.Text);
end;
Слайд 16procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
var c: Char;
MySocket: TWinSocketStream;
begin
{Как только произошло
соединение - создаем поток и ассоциируем его с сокетом (60000
- таймаут в мсек)}
MySocket := TWinSocketStream.Create(Socket,60000);
{Оператор WaitForData ждет данных из потока указанное время в мсек (в данном примере - 100) и возвращает True, если получен хотя бы один байт данных, False - если нет никаких данных из потока.}
while not MySocket.WaitForData(100) do
Application.ProcessMessages;
{Application.ProcessMessages позволяет Windows перерисовать нужные элементы окна и дает время другим программам. Если бы этого оператора не было и данные бы довольно долго не поступали, то система бы слегка "подвисла".}
MySocket.Read(c,1);
{Оператор Read читает указанное количество байт из потока (в данном примере - 1) в указанную переменную определенного типа (в примере - в переменную c типа Char). Обратите внимание на то, что Read, в отличие от ReadBuffer, не устанавливает строгих ограничений на количество принятой информации. Т.е. Read читает не больше n байтов из потока (где n - указанное число). Эта функция возвращает количество полученных байтов данных.}
MySocket.Write(c,1);
{Оператор Write аналогичен оператору Read, за тем лишь исключением, что Write пишет данные в поток.}
MySocket.Free;
{Не забудем освободить память, выделенную под поток}
end;
Слайд 17Сервер сокет
Сервер, основанный на сокетном протоколе, позволяет обслуживать сразу множество
клиентов. Причем, ограничение на их количество Вы можете указать сами
(или вообще убрать это ограничение, как это сделано по умолчанию). Для каждого подключенного клиента сервер открывает отдельный сокет, по которому Вы можете обмениваться данными с клиентом. Также отличным решением является создание для каждого подключения отдельного процесса (Thread).
Слайд 18Определение св-в Port и ServerType - чтобы к серверу могли
нормально подключаться клиенты, нужно, чтобы порт, используемый сервером точно совпадал
с портом, используемым клиентом (и наоборот). Свойство ServerType определяет тип подключения (подробнее см.ниже);
Открытие сокета - открытие сокета и указанного порта. Здесь выполняется автоматическое начало ожидания подсоединения клиентов (Listen);
Подключение клиента и обмен данными с ним - здесь подключается клиент и идет обмен данными с ним. Подробней об этом этапе можно узнать ниже в этой статье и в статье про сокеты (клиентская часть);
Отключение клиента - Здесь клиент отключается и закрывается его сокетное соединение с сервером;
Закрытие сервера и сокета - По команде администратора сервер завершает свою работу, закрывая все открытые сокетные каналы и прекращая ожидание подключений клиентов.
Слайд 19OnClientConnect - возникает, когда клиент установил сокетное соединение и ждет
ответа сервера (OnAccept);
OnClientDisconnect - возникает, когда клиент отсоединился от сокетного
канала;
OnClientError - возникает, когда текущая операция завершилась неудачно, т.е. произошла ошибка;
OnClientRead - возникает, когда клиент передал серверу какие-либо данные. Доступ к этим данным можно получить через передаваемый параметр Socket: TCustomWinSocket;
OnClientWrite - возникает, когда сервер может отправлять данные клиенту по сокету;
OnGetSocket - в обработчике этого события Вы можете отредактировать параметр ClientSocket;
Слайд 20 OnGetThread - в обработчике этого события Вы можете определить уникальный
процесс (Thread) для каждого отдельного клиентского канала, присвоив параметру SocketThread
нужную подзадачу TServerClientThread;
OnThreadStart, OnThreadEnd - возникает, когда подзадача (процесс, Thread) запускается или останавливается, соответственно;
OnAccept - возникает, когда сервер принимает клиента или отказывает ему в соединении;
OnListen - возникает, когда сервер переходит в режим ожидания подсоединения клиентов.
Слайд 21Port - номер порта для установления соединений с клиентами. Порт
у сервера и у клиентов должны быть одинаковыми. Рекомендуются значения
от 1025 до 65535, т.к. от 1 до 1024 - могут быть заняты системой. Тип: Integer;
Service - строка, определяющая службу (ftp, http, pop, и т.д.), порт которой будет использован. Это своеобразный справочник соответствия номеров портов различным стандартным протоколам. Тип: string;
Слайд 22TServerSocket.Socket (TServerWinSocket)
Итак, как же сервер может отсылать данные клиенту? А
принимать данные? В основном, если Вы работаете через события OnClientRead
и OnClientWrite, то общаться с клиентом можно через параметр ClientSocket (TCustomWinSocket). ActiveConnections (Integer) - количество подключенных клиентов;
ActiveThreads (Integer) - количество работающих процессов;
Connections (array) - массив, состоящий из отдельных классов TClientWinSocket для каждого подключенного клиента. Например, такая команда:
ServerSocket1.Socket.Connections[0].SendText('Hello!');
отсылает первому подключенному клиенту сообщение 'Hello!'. Команды для работы с элементами этого массива - также (Send/Receive)(Text,Buffer, Stream);
IdleThreads (Integer) - количество свободных процессов. Такие процессы кэшируются сервером (см. ThreadCacheSize);
LocalAddress, LocalHost, LocalPort - соответственно - локальный IP-адрес, хост-имя, порт;
RemoteAddress, RemoteHost, RemotePort - соответственно - удаленный IP-адрес, хост-имя, порт;
Методы Lock и UnLock - соответственно, блокировка и разблокировка сокета.
Слайд 23посылаемые через сокет данные могут не только объединяться в один
блок, но и разъединяться по нескольким блокам. Дело в том,
что сокет - обычный поток, но в отличие, от файлового (TFileStream), он передает данные медленнее Именно поэтому две команды:
ServerSocket1.Socket.Connections[0].SendText('Hello, ');
ServerSocket1.Socket.Connections[0].SendText('world!');
совершенно идентичны одной команде:
ServerSocket1.Socket.Connections[0].SendText('Hello, world!');
Слайд 24И именно поэтому, если Вы отправите через сокет файл, скажем,
в 100 Кб, то тому, кому Вы посылали этот блок,
придет несколько блоков с размерами, которые зависят от трафика и загруженности линии. Причем, размеры не обязательно будут одинаковыми. Отсюда следует, что для того, чтобы принять файл или любые другие данные большого размера, Вам следует принимать блоки данных, а затем объединять их в одно целое (и сохранять, например, в файл). Отличным решением данной задачи является тот же файловый поток - TFileStream (либо поток в памяти - TMemoryStream). Принимать частички данных из сокета можно через событие OnRead (OnClientRead), используя универсальный метод ReceiveBuf. Определить размер полученного блока можно методом ReceiveLength. Также можно воспользоваться сокетным потоком
Слайд 25{Прием файла через сокет}
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
l: Integer; buf: PChar; src: TFileStream;
begin
{Записываем в l
размер полученного блока}
l := Socket.ReceiveLength;
{Заказываем память для буфера}
GetMem(buf,l+1);
{Записываем в буфер полученный блок}
Socket.ReceiveBuf(buf,l);
{Открываем временный файл для записи}
src:= FileStream.Create('myfile.tmp',fmOpenReadWrite);
{Ставим позицию в конец файла}
src.Seek(0,soFromEnd);
{Записываем буфер в файл}
src.WriteBuffer(buf,l);
{Закрываем файл}
src.Free;
{Освобождаем память}
FreeMem(buf); end;
Слайд 26Посылка файлов через сокет.
{Посылка файла через сокет} procedure SendFileBySocket(filename: string);
var srcfile: TFileStream; begin
{Открываем файл filename}
srcfile := TFileStream.Create(filename,fmOpenRead);
{Посылаем его первому подключенному клиенту}
ServerSocket1.Socket.Connections[0].SendStream(srcfile);
{Закрываем файл}
srcfile.Free;
end;
Слайд 27procedure TForm1.Button1Click(Sender: TObject); begin
{Определяем порт и запускаем сервер}
ServerSocket1.Port
:= 1025;
{Метод Insert вставляет строку в массив в указанную
позицию}
Memo2.Lines.Insert(0,'Server starting');
ServerSocket1.Open;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
{Останавливаем сервер}
ServerSocket1.Active := False; Memo2.Lines.Insert(0,'Server stopped');
end;
procedure TForm1.ServerSocket1Listen(Sender: TObject; Socket: TCustomWinSocket);
begin
{Здесь сервер "прослушивает" сокет на наличие клиентов}
Memo2.Lines.Insert(0,'Listening on port '+IntToStr(ServerSocket1.Port));
end;
Слайд 28procedure TForm1.ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket);
begin
{Здесь сервер принимает клиента}
Memo2.Lines.Insert(0,'Client connection accepted'); end;
procedure TForm1.ServerSocket1ClientConnect
(Sender: TObject; Socket: TCustomWinSocket);
begin
{Здесь клиент подсоединяется} Memo2.Lines.Insert(0,'Client connected');
end;
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
{Здесь клиент отсоединяется}
Memo2.Lines.Insert(0,'Client disconnected');
end;
Слайд 29procedure TForm1.ServerSocket1ClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
{Произошла ошибка - выводим ее код} Memo2.Lines.Insert(0,'Client error. Code
= '+IntToStr(ErrorCode));
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
begin
{От клиента получено сообщение - выводим его в Memo1} Memo2.Lines.Insert(0,'Message received from client'); Memo1.Lines.Insert(0,'> '+Socket.ReceiveText);
end;
procedure TForm1.ServerSocket1ClientWrite(Sender: TObject; Socket: TCustomWinSocket);
begin
{Теперь можно слать данные в сокет} Memo2.Lines.Insert(0,'Now can write to socket');
end;
Слайд 30procedure TForm1.ServerSocket1GetSocket(Sender: TObject; Socket: Integer; var ClientSocket: TServerClientWinSocket); begin
Memo2.Lines.Insert(0,'Get
socket');
end;
procedure TForm1.ServerSocket1GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread);
begin
Memo2.Lines.Insert(0,'Get Thread');
end;
procedure TForm1.ServerSocket1ThreadEnd(Sender: TObject; Thread: TServerClientThread);
begin
Memo2.Lines.Insert(0,'Thread end');
end;
procedure TForm1.ServerSocket1ThreadStart(Sender: TObject; Thread: TServerClientThread);
begin
Memo2.Lines.Insert(0,'Thread start');
end;
procedure TForm1.Button3Click(Sender: TObject);
var i: Integer; begin
{Посылаем ВСЕМ клиентам сообщение из Edit1}
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
begin ServerSocket1.Socket.Connections[i].SendText(Edit1.Text);
end;
Memo1.Lines.Insert(0,'< '+Edit1.Text);
end;