Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
9
Добавлен:
12.03.2016
Размер:
112.64 Кб
Скачать

Port - номер порта для установления соединений с клиентами. Порт у сервера и у клиентов должны быть одинаковыми. Рекомендуются значения от 1025 до 65535, т.к. от 1 до 1024 - могут быть заняты системой. Тип: Integer;

Service - строка, определяющая службу (ftp, http, pop, и т.д.), порт которой будет использован. Это своеобразный справочник соответствия номеров портов различным стандартным протоколам. Тип:

string;

TServerSocket.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 - соответственно, блокировка и разблокировка сокета.

посылаемые через сокет данные могут не только объединяться в один блок, но и разъединяться по нескольким блокам. Дело в том, что сокет - обычный поток, но в отличие, от файлового (TFileStream), он передает данные медленнее Именно поэтому две команды: ServerSocket1.Socket.Connections[0].SendText(' Hello, '); ServerSocket1.Socket.Connections[0].SendText(' world!');

совершенно идентичны одной команде: ServerSocket1.Socket.Connections[0].SendText(' Hello, world!');

И именно поэтому, если Вы отправите через сокет файл, скажем, в 100 Кб, то тому, кому Вы посылали этот блок, придет несколько блоков с размерами, которые зависят от трафика и загруженности линии. Причем, размеры не обязательно будут одинаковыми. Отсюда следует, что для того, чтобы принять файл или любые другие данные большого размера, Вам следует принимать блоки данных, а затем объединять их в одно целое (и сохранять, например, в файл). Отличным решением данной задачи является тот же файловый поток - TFileStream (либо поток в памяти - TMemoryStream). Принимать частички данных из сокета можно через событие OnRead (OnClientRead), используя универсальный метод ReceiveBuf. Определить размер полученного блока можно методом ReceiveLength. Также можно воспользоваться сокетным потоком

{Прием файла через сокет}

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;

Посылка файлов через сокет.

{Посылка файла через сокет} procedure SendFileBySocket(filename: string);

var srcfile: TFileStream; begin

{Открываем файл filename}

srcfile := TFileStream.Create(filename,fmOpenRead);

{Посылаем его первому подключенному клиенту}

ServerSocket1.Socket.Connections[0].SendStream(srcfil

e);

{Закрываем файл}

srcfile.Free;

end;

procedure 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;

procedure 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;

procedure 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;

procedure 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;

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.

Соседние файлы в папке Операционные системы презентации