Проверка на поврзувањето на приклучокот Делфи. Делфи. Сокет програмирање во Делфи. Испраќање и примање сложени податоци

Сокети (од штекер (англиски) - конектор, штекер) се софтверски интерфејс, кој обезбедува размена на информации помеѓу процесите.

Една од главните предности на приклучната комуникација во мрежата е нејзината флексибилност. Главниот принцип на работа со сокети е да се испрати низа бајти на друг компјутер, тоа може да биде едноставна текстуална порака или датотека.

Важно е да се направи разлика помеѓу два типа на приклучоци: клиентски приклучоци , И серверски приклучоци .

За работа со приклучоци од типот „клиент“ во Делфи, постои компонента TClientSocket, можете да работите со приклучоци за „сервер“ користејќи ја компонентата TServerSocket.

Инсталирање на компоненти

Често компонентите TServerSocket и TClientSocket не се вклучени во стандардниот инсталациски пакет на Delphi, но тие можат да се инсталираат одделно.

Одете во табулаторот „Интернет“ компоненти и проверете дали таму се присутни компонентите TServerSocket и TClientSocket, ако не, инсталирајте ги. Одете во менито „Component/Install Packages“, потоа кликнете на копчето „Add“. Во полето за дијалог што се отвора, треба да ја пронајдете датотеката „dclsocketsXX.bpl“ (се наоѓа во папката за отпадоци, која се наоѓа во папката со Delphi), каде што XX е нумеричкиот број на верзијата на вашиот Delphi. Лоцирајте ја датотеката, кликнете Отвори, а потоа кликнете OK во прозорецот Install Packages. Сега, две компоненти се појавија во табулаторот „Интернет“ - TServerSocket и TClientSocket.

Работа со клиентски приклучоци (tClientSocket)

1) Дефиниција за својства на пристаниште и домаќин.За успешно поврзување својства пристаништеИ Домаќинна компонентата TClientSocket треба да и се доделат некои вредности. Во својството Port, треба да го наведете бројот на портата за поврзување (1 - 65535, но подобро е да се земе од опсегот 1001 - 65535, бидејќи броевите до 1000 може да бидат окупирани од системските услуги).

Домаќин- име на домаќин или IP адреса на компјутерот на кој сакате да се поврзете. На пример, rus.delphi.com или 192.128.0.0.

2) Отворање на штекер.Сокетот ќе го сметаме како редица знаци што се пренесуваат од еден на друг компјутер. Можете да отворите штекер со повикување на методот отворени(компонента TClientSocket) или со доделување вредност Вистинаимот Активен. Тука би било корисно да се стави управувач за исклучоци во случај на неуспешна врска.

3) Испраќање/примање податоци.

4) Затворање на штекерот.По завршувањето на размената на податоци, треба да го затворите штекерот со повикување на методот затворикомпонента TClientSocketили со доделување вредност Неточноимот Активен.

Основни својства на компонентата TClientSocket

Индикација за тоа дали штекерот е отворен или затворен. Отворено - Вистинска вредност, затворено - Неточна вредност. Достапно за снимање.

Име на домаќин за поврзување

IP адресата на компјутерот на кој треба да се поврзете. За разлика од Host, овде може да се наведе само IP. Разликата е во тоа што ако Host содржи буквално име на компјутер, тогаш IP ќе биде побарана од DNS

Бројот на портата на компјутерот на кој треба да се поврзете (1-65535)

Тип на клиент

Го содржи типот на пренос на податоци:

ctБлокирање- синхрони пренос ( На ЧитањеИ OnWriteне функционира). Синхрониот тип на конекција е погоден за пренос на размена на податоци;

ctНеБлокирање- асинхрон пренос (испраќањето / примањето податоци може да се врши со помош на настани На ЧитањеИ OnWrite)

Основни методи на компонентата TClientSocket

Отвора сокет (поставување на својството Active на True)

Го затвора штекерот (поставување на својството Active на False)

Главни настани на компонентата TClientSocket

OnConnect

Се појавува кога ќе се воспостави врска. Во управувачот, веќе можете да започнете овластување или испраќање / примање податоци

Наповрзување

Се појавува и кога е поврзан. Се разликува од OnConnect по тоа што врската сè уште не е воспоставена. Најчесто се користи, на пример, за ажурирање на статусот

Вклучи Исклучи

Настанот се случува кога штекерот е затворен од вашата програма, од далечинскиот компјутер или поради дефект

Настанот е подигнат на грешка. Додека се отвора штекерот, овој настан нема да помогне да се открие грешката. За да избегнете порака за грешка од Windows, најдобро е да се грижите за внатрешниот третман на исклучоци со ставање отворени изјави во " пробај..освен »

OnLookup

Настанот се случува кога се обидувате да добиете IP адреса од DNS

Настанот се случува кога оддалечен компјутер ви испраќа некои податоци. Кога повикувате OnRead, можно е да се обработат примените податоци

Настанот се подига кога на вашата програма ќе му биде дозволено да запишува податоци во штекерот

Оваа статија ќе ги опфати основните својства и функции Делфи компоненти: TClientSocket и TServerSocket - се користат за работа со мрежата користејќи го протоколот TCP\IP.

Внимание!Ако користите верзија на Delphi повисока од 6.0, тогаш прво мора да инсталирате Sockets Components, во сите верзии на Delphi тоа се прави на следниов начин:

  • Одете во дијалогот Инсталирај пакети…: (Главно мени) Компонента -> Инсталирај пакети;
  • Кликнете на копчето Додај…, по што ја наоѓаме папката Bin на вашиот Delphi (на пр.: C:\Program Files\Borland\Delphi 7\bin , или C:\Program Files\Embarcadero\RAD Studio\7.0\Bin);
  • Во пронајдената папка Bin, веќе бараме датотека dclsockets [броеви овде].bpl, кликнете OK;
  • Среќни сме, затоа што сега имаме две прекрасни компоненти TServerSocket и TClientSocket во табулаторот на панелот за компоненти на табот Интернет.

Кога развивате какви било мрежни апликации, развојот обично секогаш започнува од серверот (се разбира, ако имате тим, дизајнерите од предниот дел може да почнат да работат на клиентот). За да го имплементирате серверот, изненадувачки, треба да користите TServerSocket.

Основни својства:

  • Активен– полето за тип бул, кога е поставено на true – серверот е стартуван, може да се користи и со доделување специфични вредности и со повикување на функциите ServerSocket1.Open (… Active:=true;) или ServerSocket1.Close (… Active:=false).
  • пристаниште- портот на кој серверот ќе слуша (прима клиенти), која било вредност што не е окупирана од други сервери во системот во опсегот цел број.

Главни настани:

  • OnListen- се нарекува кога серверот е поставен на режим на слушање, може да се користи кога треба да го одредиме вистинското време на започнување на серверот.
  • OnClientRead– се повикува во моментот на примање податоци од клиентот.
  • OnClient Error
  • OnClientConnect- Се повикува кога нов клиент се приклучува на серверот.
  • OnClientDisconnect- спротивен настан од настанот, OnClientConnect

секоја функција на настан има свој атрибут Сокет: TCustomWinSocket, покажувач кон објектот сокет во кој се наоѓаме овој моментработа, ако треба да одговориме нешто или да направиме нешто со клиентот што го активирал настанот, треба да го користиме овој конкретен објект, во сите други случаи што ги користиме ServerSocket1.Socket, слична е ситуацијата и со клиентската компонента.

Својства и функции само за читање:

  • – го враќа бројот на активни конекции.
  • ServerSocket1.Socket.Поврзувања– низа објекти од типот TCustomWinSocket, низа од сите објекти поврзани со клиенти, броењето на индексите започнува од 0, должината на низата е еднаква на ServerSocket1.Socket.ActiveConnections.
  • Функции и својства што се однесуваат на елементите на низата ServerSocket1.Socket.Connections и атрибутот Socket предаден на функцијата за настан на серверот:
  • Socket.LocalHost
  • Socket.LocalAddress– ја враќа IP адресата на серверот.
  • Socket.RemoteHost
  • Socket.RemoteAddress– ја враќа IP адресата на клиентот.
  • Socket.ReceiveText- враќа текстуална порака добиена од клиентот, по што го брише баферот, може да се користи само 1 пат, за 1 прием.
  • Socket.SendText(Text)– испраќа текстуална порака од типот Text до клиентот низа.

За компонентата TClientSocket, сè е скоро исто, само обратно + главната визуелна разлика помеѓу серверот и клиентот, серверот во системот може да се стартува 1 на 1 вредност на портата, само RAM меморијата ве ограничува во бројот на клиенти.

Основни својства:

  • Активен– полето со бул тип, кога е поставено на true – клиентот се обидува да се поврзе со серверот, може да се користи и со доделување специфични вредности и со повикување на функциите ClientSocket1.Open (… Active:=true;) или ClientSocket1.Close (… Active:=false).
  • пристаниште– порта на која клиентот може да се поврзе со серверот, која било вредност во опсегот цел број.
  • адреса– IPv4 адреса на типот на серверот низашема 255.255.255.255 со која ќе се поврзе клиентот.

Главни настани:

  • На Читање– се повикува кога се добиваат податоци од север.
  • OneError- Се повикува кога ќе се појави грешка при пренос на податоци.
  • Наповрзување- Се повикува кога клиентот се поврзува на серверот.
  • Вклучи Исклучи- спротивен настан од настанот, Наповрзување, повикан при исклучување на клиентот од серверот.

Својства и функции само за читање:

  • ClientSocket1.Socket.SendText() низа
  • Socket.LocalHost– го враќа името на клиентот на мрежата.
  • Socket.LocalAddress– ја враќа IP адресата на клиентот.
  • Socket.RemoteHost– го враќа името на серверот на мрежата.
  • Socket.RemoteAddress– ја враќа IP адресата на серверот.
  • Socket.ReceiveText– враќа текстуална порака добиена од серверот, по што го брише баферот, може да се користи само 1 пат, за 1 прием.
  • Socket.SendText(Text)– испраќа текстуална порака од типот Text до серверот низа.

Обезбедените информации се доволни за да се имплементира мал сервер разговор што задоволува Услови за работење: internet_sockets.doc (Word Doc 97-2003, 26,5 Kb).

Оваа статија е напишана во недела, 10 октомври 2010 година во 01:24 часот во делот . Можете да се претплатите на ажурирања на коментари на статијата -. Ти можеш


Вовед


Оваа статија е за создавање на апликации за клиент/сервер базирана на сокети во Borland Delphi („сокети“ - гнезда). За разлика од претходната статија на тема сокети, овде ќе го анализираме создавањето на серверски апликации.

Веднаш треба да се забележи дека за коегзистенција на посебни клиентски и серверски апликации, не е неопходно да има неколку компјутери. Доволно е да имате само еден на кој можете истовремено да ги стартувате и серверот и клиентот. Во овој случај, треба да го користите името на домаќинот како име на компјутерот на кој сакате да се поврзете. локален домаќинили IP адреса - 127.0.0.1 .

Значи, да почнеме со теоријата. Ако сте верен лекар (и не можете да видите ниту еден алгоритам со вашите очи), тогаш треба да го прескокнете овој дел.

Алгоритам на сокет сервер


Што прави сокет-серверот?.. Како функционира?.. Сервер базиран на сокет-протоколот ви овозможува да опслужувате многу клиенти одеднаш. Покрај тоа, можете сами да наведете ограничување на нивниот број (или целосно да го отстраните ова ограничување, како што се прави стандардно). За секој поврзан клиент, серверот отвора посебен сокет, преку кој можете да разменувате податоци со клиентот. Исто така одлично решение е да се создаде посебен процес (Thread) за секоја врска.

Следното е пример за тоа како работи сокет-серверот во апликациите на Делфи:

Ајде да ја анализираме шемата подетално:

  • Дефинирање на својства во Port и ServerType - за да може клиентите нормално да се поврзат со серверот, портата што ја користи серверот мора точно да одговара на портата што ја користи клиентот (и обратно). Својството ServerType го одредува типот на врската (видете подолу за детали);
  • отвор на штекерот - Отворање на штекер и наведената порта. Овде се врши автоматско започнување на чекање за поврзување на клиентите ( Слушај);
  • Поврзување на клиент и размена на податоци со него - овде клиентот се поврзува и со него се разменуваат податоци. Можете да дознаете повеќе за оваа фаза подоцна во овој напис и во статијата за приклучоци (страна на клиентот);
  • Оневозможување на клиент - Овде клиентот се исклучува и неговата приклучна врска со серверот е затворена;
  • Затворање на серверот и штекерот - По наредба на администраторот, серверот ја прекинува својата работа, затворајќи ги сите отворени штекери канали и прекинувајќи да чека за поврзување со клиентот.

Треба да се напомене дека точките 3-4 се повторуваат многу пати, т.е. овие ставки се извршуваат за секоја нова клиентска врска.

Забелешка : Во моментов има многу малку документација за сокетите во Делфи, па ако сакате да ја проучите оваа тема што е можно подлабоко, тогаш ве советувам да ја разгледате литературата и електронската документација за Unix/Linux системите - таму МногуТеоријата за работа со приклучоци е добро опишана. Дополнително, има многу примери на приклучоци апликации за овие оперативни системи (но најмногу во C/C++ и Perl).

Краток опис на компонентата TServerSocket


Тука ќе се запознаеме главенсвојства, методи и настани на компонентата TServerSocket.

Својства

Сокет - класата TServerWinSocket, преку која имате пристап до отворени сокет канали. Следно, ќе го разгледаме овој имот подетално, бидејќи. тоа е, всушност, еден од главните. Тип: TServerWinSocket ;
Тип на сервер - тип на сервер. Може да земе една од двете вредности: stNonBlocking- синхрона работа со клиентски приклучоци. Со овој тип на сервер, можете да работите со клиенти преку настани OnClientReadИ OnClientWrite. stThreadBlocking- асинхрон тип. Посебен процес (Thread) е креиран за секој канал со штекер на клиентот. Тип: TServerType ;
ThreadCacheSize - бројот на клиентски процеси (Thread) кои ќе бидат кеширани од серверот. Овде треба да ја изберете просечната вредност во зависност од оптоварувањето на вашиот сервер. Кеширањето се случува со цел да не се создава посебен процес секој пат и да не се убие затворениот штекер, туку да се остават за понатамошна употреба. Тип: Цел број ;
Активен - индикатор за тоа дали серверот е моментално активен или не. Тоа е всушност вредноста Вистинапокажува дека серверот работи и е подготвен да прима клиенти, и Неточно- серверот е исклучен. За да го стартувате серверот, само треба да го поставите ова својство на Вистина. Тип: Булова ;
пристаниште - број на порта за воспоставување врски со клиенти. Портата на серверот и клиентите мора да бидат исти. Се препорачуваат вредности од 1025 до 65535, како од 1 до 1024 - може да биде окупиран од системот. Тип: Цел број ;
Сервис - низа што ја дефинира услугата ( ftp, http, поп, итн.) чија порта ќе се користи. Ова е еден вид референтна книга за усогласување на броевите на портите со различни стандардни протоколи. Тип: низа ;

отворени - Го стартува серверот. Во суштина, оваа команда е идентична со доделување вредност Вистинаимот Активен;
затвори - Го запира серверот. Во суштина, оваа команда е идентична со доделување вредност Неточноимот Активен.

OnClientConnect - се јавува кога клиентот воспоставил конекција со сокет и чека одговор од серверот ( OnAccept);
OnClientDisconnect - се јавува кога клиентот се исклучи од каналот за штекер;
OnClient Error - се јавува кога тековната операција е неуспешна, т.е. Се појави грешка;
OnClientRead - се јавува кога клиентот испратил некои податоци до серверот. До овие податоци може да се пристапи преку положениот параметар Сокет: TCustomWinSocket;
OnClientWrite - се јавува кога серверот може да испрати податоци до клиентот на штекерот;
OnGetSocket - во управувачот на овој настан, можете да го уредите параметарот ClientSocket;
OnGetThread - во управувачот на овој настан, можете да дефинирате единствен процес (Thread) за секој поединечен канал на клиентот со поставување на параметарот SocketThreadсаканата подзадача TServerClientThread;
OnThreadStart , НаThreadEnd - се јавува кога подзадача (процес, Тема) започнува или запира, соодветно;
OnAccept - се јавува кога серверот прифаќа клиент или одбива врска;
OnListen - Се појавува кога серверот влегува во режим на чекање за поврзување на клиентите.


TServerSocket.Socket(TServerWinSocket)


Значи, како може серверот да испраќа податоци до клиентот? Што е со примањето податоци? Во основа, ако работите преку настани OnClientReadИ OnClientWrite, тогаш можете да комуницирате со клиентот преку параметарот ClientSocket (TCustomWinSocket). Можете да прочитате за работата со оваа класа во написот за клиентските приклучоци. испраќањето/испраќањето податоци преку оваа класа е слично - методи (Испрати/Примање) (Текст, бафер, тек). Исто така при работа со TServerSocket.Socket. Меѓутоа, бидејќи Бидејќи размислуваме за сервер, треба да се истакнат некои корисни својства и методи:

  • ActiveConnections (Цел број) - број на поврзани клиенти;
  • ActiveThreads (Цел број) е бројот на процеси кои се извршуваат;
  • Врски (низа) е низа која се состои од поединечни TClientWinSocket класи за секој поврзан клиент. На пример, оваа команда:
    ServerSocket1.Socket.Connections.SendText("Здраво!");
    испраќа порака „Здраво!“ до првиот поврзан клиент. Наредбите за работа со елементи од оваа низа се исто така (Испрати/Примање) (Текст, бафер, тек);
  • IdleThreads (Цел број) е бројот на слободни процеси. Ваквите процеси се кеширани од серверот (види ThreadCacheSize);
  • локална адреса, локален домаќин, локално пристаниште- соодветно - локална IP адреса, име на домаќин, порта;
  • далечинска адреса, далечински домаќин, далечинска порта- соодветно - далечинска IP адреса, име на домаќин, порта;
  • Методи заклучувањеИ отклучување- соодветно, блокирање и деблокирање на штекер.

Вежба и примери


Сега да го погледнеме погоре конкретен пример. Можете да преземете готови извори со кликнување.

Значи, да погледнеме многу добар пример за работа со TServerSocket (овој пример е највизуелното помагало за учење на оваа компонента). Изворниот код подолу ја покажува евиденцијата на сите важни настани на серверот, плус можноста за примање и испраќање текстуални пораки:

Пример 1Вклучување и учење работа на серверот, испраќање/примање пораки преку сокети

(... Тука доаѓа заглавието на датотеката и дефиницијата на формата TForm1 и нејзиниот примерок Form1)
(Види го целиот извор)
процедура TForm1.Button1Click(Испраќач: TObject); започне (Ја дефинираме портата и го стартуваме серверот) ServerSocket1.Port:= 1025; (Методот Insert вметнува низа во низата на одредената позиција) Memo2.Lines.Insert(0"Серверот започнува"); ServerSocket1.Open; крај; процедура TForm1.Button2Click(Испраќач: TObject); започне (Сопрете го серверот) ServerSocket1.Active:= Неточно; Memo2.Lines.Insert(0"Серверот запре"); крај; процедура TForm1.ServerSocket1Listen(Испраќач: TObject; Сокет: TCustomWinSocket); започне (Тука серверот „слуша“ на штекерот за клиенти) Memo2.Lines.Insert(0,"Слушање на порта "+IntToStr(ServerSocket1.Port)); крај; процедура TForm1.ServerSocket1Accept(Испраќач: TObject; Сокет: TCustomWinSocket); започне (Тука серверот го прифаќа клиентот) Memo2.Lines.Insert(0"Прифатена е врската со клиентот"); крај; процедура TForm1.ServerSocket1ClientConnect(Испраќач: TObject; Сокет: TCustomWinSocket); започне (Тука клиентот се поврзува) Memo2.Lines.Insert(0"Поврзан клиент"); крај; процедура TForm1.ServerSocket1ClientDisconnect(Испраќач: TObject; Сокет: TCustomWinSocket); започне (Тука клиентот се исклучува) Memo2.Lines.Insert(0"Клиентот е исклучен"); крај; процедура TForm1.ServerSocket1ClientError(Испраќач: TObject; Сокет: TCustomWinSocket; ErrorEvent: TErrorEvent; var Код на грешка: Цел број); започне (Се појави грешка - испечатете го неговиот код) Memo2.Lines.Insert(0,"Грешка на клиентот. Код = "+IntToStr(ErrorCode)); крај; процедура TForm1.ServerSocket1ClientRead(Испраќач: TObject; Сокет: TCustomWinSocket); започне (Добиена е порака од клиентот - ја прикажуваме во Memo1) Memo2.Lines.Insert(0"Порака добиена од клиентот"); Memo1.Lines.Insert(0,"> "+Socket.ReceiveText); крај; процедура TForm1.ServerSocket1ClientWrite(Испраќач: TObject; Сокет: TCustomWinSocket); започне (Сега можете да испраќате податоци до штекерот) Memo2.Lines.Insert(0,"Сега може да пишува во штекер"); крај; процедура TForm1.ServerSocket1GetSocket(Испраќач: TObject; Сокет: Цел број; var ClientSocket: TServerClientWinSocket); започне Memo2.Lines.Insert(0"Get socket"); крај; процедура TForm1.ServerSocket1GetThread(Испраќач: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread); започне Memo2.Lines.Insert(0"Get Thread"); крај; процедура TForm1.ServerSocket1ThreadEnd(Испраќач: TObject; Тема: TServerClientThread); започне Memo2.Lines.Insert(0"Крај на темата"); крај; процедура TForm1.ServerSocket1ThreadStart(Испраќач: TObject; Тема: TServerClientThread); start Memo2.Lines.Insert(0"Почеток на темата"); крај; процедура TForm1.Button3Click(Испраќач: TObject); var i: Цел број; започне (Испратете порака на СИТЕ клиенти од Edit1) за i:= 0 до ServerSocket1.Socket.ActiveConnections-1 започнува ServerSocket1.Socket.Connections[i].SendText(Edit1.Text); крај; Memo1.Lines.Insert(0,"

Техники за работа со TServerSocket (и само сокети)


Складирање единствени податоци за секој клиент.


Сигурно, ако вашиот сервер ќе опслужува многу клиенти, тогаш ќе треба да складирате некои информации за секој клиент (име, итн.), и со врзување на овие информации за сокетот на овој клиент. Во некои случаи, да се прави сето ова рачно (врзување на рачката на штекерот, низи клиенти, итн.) не е многу погодно. Затоа, постои посебен имот за секој штекер - Податоци. Всушност, податоците се само покажувач. Затоа, кога пишувате податоци за клиентот на овој имот, бидете внимателни и следете ги правилата за работа со покажувачи (распределба на меморија, заклучување на типот итн.)!

Испраќање датотеки преку приклучок.


Овде ќе разгледаме испраќање датотеки преку сокет (на барање на JINX) :-). Значи, како да испратите датотека преку приклучок? Многу едноставно! Треба само да ја отворите оваа датотека како пренос на датотеки (TFileStream) и да ја испратите преку сокет (SendStream)! Да го погледнеме ова со пример:

Треба да се напомене дека методот sendstreamсе користи не само од серверот, туку и од клиентот ( ClientSocket1.Socket.SendStream(srcfile))

Зошто може неколку блокови да се комбинираат во еден за време на преносот?


Ова го бара и JINX :-). Голема благодарност до него за ова! Значи, прво, треба да се забележи дека податоците испратени преку штекерот не само што можат да се комбинираат во еден блок, туку и да се поделат во неколку блокови. Факт е дека сокетот е нормален поток, но за разлика од, да речеме, пренос на датотеки (TFileStream), тој ги пренесува податоците побавно (разбирате - мрежата, ограничениот сообраќај итн.). Затоа две команди:
ServerSocket1.Socket.Connections.SendText("Здраво, ");
ServerSocket1.Socket.Connections.SendText("свет!");
се целосно идентични со една команда:
ServerSocket1.Socket.Connections.SendText("Здраво, свет!");

И затоа, ако испратите датотека, да речеме, 100 Kb, преку штекерот, тогаш лицето на кое сте го испратиле овој блок ќе добие неколку блокови со големини кои зависат од сообраќајот и оптоварувањето на линијата. Покрај тоа, димензиите не мора да бидат исти. Следи дека за да се добие датотека или било кој друг податок голема величина, Треба да земете блокови од податоци и потоа да ги комбинирате во една целина (и да зачувате, на пример, во датотека). Одлично решение за овој проблем е истиот проток на датотеки - TFileStream (или поток во меморијата - TMemoryStream). Можете да примате честички на податоци од штекерот преку настанот OnRead (OnClientRead), користејќи го универзалниот метод ReceiveBuf. Можете да ја одредите големината на добиениот блок користејќи го методот Должина на примање. Можете исто така да користите приклучок за пренос (видете ја статијата TClientSocket). И еве мал пример (приближно):

Како да следите штекер


Ова прашање е сложено и бара долго разгледување. Засега, само ќе забележам дека секогаш можете да го следите штекерот создаден од вашата програма :-). Сокетите (како и повеќето објекти во Windows) имаат своја рачка (рачка), напишана во својството Handle. Значи, откако го научивте овој дескриптор, можете слободно да контролирате кој било сокет (дури и оние создадени од туѓа програма)! Сепак, најверојатно, за да го следите туѓиот приклучок, ќе мора исклучиво да ги користите функциите на WinAPI Sockets.


Оваа статија ги прикажува основните трикови за работа со компонентата TServerSocket во Delphi и неколку општи трикови за комуникација преку сокети. Ако имате какви било прашања - испратете ми ги на е-пошта: [заштитена е-пошта], и уште подобро - пишете во форумот на оваа страница (Делфи. Општи прашања), за да можат другите корисници да го видат вашето прашање и да се обидат да одговорат!

Карик Николај ( Нитро). Московскиот регион, Жуковски

Оваа статија е за создавање на апликации за клиент/сервер базирана на сокети во Borland Delphi. За разлика од претходната статија на тема сокети, овде ќе го анализираме создавањето на серверски апликации.
Веднаш треба да се забележи дека за коегзистенција на посебни клиентски и серверски апликации, не е неопходно да има неколку компјутери. Доволно е да имате само еден на кој можете истовремено да ги стартувате и серверот и клиентот. Во овој случај, треба да го користите името на домаќинот localhost или IP адресата - 127.0.0.1 како име на компјутерот на кој сакате да се поврзете.
Значи, да почнеме со теоријата. Ако сте верен лекар (и не можете да видите ниту еден алгоритам со вашите очи), тогаш треба да го прескокнете овој дел.
Алгоритам на сокет сервер
Што прави сокет-серверот?.. Како функционира?.. Сервер базиран на сокет-протоколот ви овозможува да опслужувате многу клиенти одеднаш. Покрај тоа, можете сами да наведете ограничување на нивниот број (или целосно да го отстраните ова ограничување, како што се прави стандардно). За секој поврзан клиент, серверот отвора посебен сокет, преку кој можете да разменувате податоци со клиентот. Исто така одлично решение е да се создаде посебен процес (Thread) за секоја врска.
Следното е пример за тоа како работи сокет-серверот во апликациите на Делфи:

Да ја разгледаме шемата подетално: · Дефиниција на својствата Port и ServerType - за да може клиентите нормално да се поврзат со серверот, портата што ја користи серверот мора точно да одговара на портата што ја користи клиентот (и обратно). Својството ServerType го одредува типот на врската (видете подолу за детали); · Отворен сокет - отворен штекер и одредена порта. Овде се врши автоматско започнување на чекање за поврзување на клиентите (Listen); · Поврзување на клиент и размена на податоци со него - овде се поврзува клиент и со него се разменуваат податоци. Можете да дознаете повеќе за оваа фаза подоцна во овој напис и во статијата за приклучоци (страна на клиентот); · Client Disconnect - Овде клиентот е исклучен и неговата приклучна врска со серверот е затворена; · Затворање на серверот и штекерот - По наредба на администраторот, серверот се исклучува, затворајќи ги сите отворени канали на сокетот и престанува да чека за поврзување со клиентот.
Треба да се напомене дека точките 3-4 се повторуваат многу пати, т.е. овие ставки се извршуваат за секоја нова клиентска врска.
Забелешка: Во моментов има многу малку документација за сокетите во Делфи, па ако сакате да ја проучите оваа тема што е можно подлабоко, ве советувам да ја разгледате литературата и електронската документација за системите Unix / Linux - теоријата за работа со сокети е многу добро опишана таму. Дополнително, има многу примери на приклучоци апликации за овие оперативни системи (но најмногу во C/C++ и Perl).
Краток опис на компонентата TServerSocket
Овде ќе се запознаеме со главните својства, методи и настани на компонентата.
Својства
Socket - TServerWinSocket класа преку која имате пристап до отворени сокет канали. Следно, ќе го разгледаме овој имот подетално, бидејќи. тоа е, всушност, еден од главните. Тип: TServerWinSocket;
ServerType - тип на сервер. Може да земе една од двете вредности: stNonBlocking - синхрона работа со приклучоци за клиент. Со овој тип на сервер, можете да работите со клиенти преку настаните OnClientRead и OnClientWrite. stThreadBlocking е асинхрон тип. Посебен процес (Thread) е креиран за секој канал со штекер на клиентот. Тип: TServerType;
ThreadCacheSize - бројот на клиентски процеси (Thread) кои ќе бидат кеширани од серверот. Овде треба да ја изберете просечната вредност во зависност од оптоварувањето на вашиот сервер. Кеширањето се случува со цел да не се создава посебен процес секој пат и да не се убие затворениот штекер, туку да се остават за понатамошна употреба. Тип: Цел број;
Активен - индикатор за тоа дали серверот е моментално активен или не. Тоа е, всушност, вистинската вредност покажува дека серверот работи и е подготвен да прима клиенти, а False - серверот е исклучен. За да го стартувате серверот, само треба да го поставите ова својство на True. Тип: Булова
Порт - број на порта за воспоставување врски со клиенти. Портата на серверот и клиентите мора да бидат исти. Се препорачуваат вредности од 1025 до 65535, како од 1 до 1024 - може да биде окупиран од системот. Тип: Цел број;
Услуга - низа што ја одредува услугата (ftp, http, pop, итн.) чија порта ќе се користи. Ова е еден вид референтна книга за усогласување на броевите на портите со различни стандардни протоколи. Тип: низа
Методи
Отвори - го стартува серверот. Во суштина, оваа команда е идентична со поставувањето на вредноста True на својството Active;
Затвори - го запира серверот. Во суштина, оваа команда е идентична со поставувањето на вредноста False на својството Active.
Настани
OnClientConnect - се јавува кога клиентот има воспоставено сокет конекција и чека одговор на серверот (OnAccept);
OnClientDisconnect - се зголемува кога клиентот се исклучил од приклучниот канал.
OnClientError - Се зголемува кога тековната операција е неуспешна, т.е. Се појави грешка;
OnClientRead - се активира кога клиентот испратил некои податоци до берверот. До овие податоци може да се пристапи преку испорачаниот параметар Socket: TCustomWinSocket;
OnClientWrite - се јавува кога серверот може да испрати податоци до клиентот на штекерот;
OnGetSocket - во овој управувач за настани можете да го уредувате параметарот ClientSocket;
OnGetThread - во управувачот на овој настан, можете да дефинирате единствен процес (Thread) за секој посебен канал на клиентот со доделување на потребната подзадача TServerClientThread на параметарот SocketThread;
OnThreadStart, OnThreadEnd - се јавува кога подзадача (процес, Тема) започнува или запира, соодветно;
OnAccept - се активира кога серверот прифаќа или негира врска со клиентот;
OnListen - се подига кога серверот чека да се поврзат клиентите.
TServerSocket.Socket(TServerWinSocket)
Значи, како може серверот да испраќа податоци до клиентот? Што е со примањето податоци? Во основа, ако работите преку настаните OnClientRead и OnClientWrite, тогаш можете да комуницирате со клиентот преку параметарот ClientSocket (TCustomWinSocket). Можете да прочитате за работата со оваа класа во написот за клиентските приклучоци. испраќањето/испраќањето податоци преку оваа класа е слично - методи (Испрати/Примање) (Текст, бафер, тек). Исто така при работа со TServerSocket.Socket. Меѓутоа, бидејќи овде размислуваме за сервер, треба да се истакнат некои корисни својства и методи: ActiveConnections (Integer) - бројот на поврзани клиенти; ActiveThreads (Цел број) - бројот на процеси кои се извршуваат; ·Конекции (низа) - низа која се состои од посебни класи TClientWinSocket за секој поврзан клиент. На пример, следнава команда: ServerSocket1.Socket.Connections.SendText("Здраво!"); Испраќа порака "Здраво!" до првиот поврзан клиент. Наредбите за работа со елементи од оваа низа се исто така (Испрати/Примање) (Текст, бафер, тек); ·IdleThreads (Цел број) - бројот на неактивен процеси. Таквите процеси се кеширани од серверот (видете ThreadCacheSize); LocalAddress, LocalHost, LocalPort - соодветно - локална IP адреса, име на домаќин, порта; ·RemoteAddress, RemoteHost, RemotePort - соодветно - далечинска IP адреса, име на домаќин, порта; ·Методи Заклучување и Отклучување - соодветно, блокирање и деблокирање на штекер.
Вежба и примери
Сега да го погледнеме погоре со конкретен пример. Можете да преземете готови извори со кликнување овде.
Значи, да погледнеме многу добар пример за работа со TServerSocket (овој пример е највизуелното помагало за учење на оваа компонента). Изворите подолу покажуваат евиденција на сите важни настани на серверот, плус способност за примање и испраќање текстуални пораки:
Пример 1. Најава и проучување на работата на серверот, испраќање/примање пораки преку сокети.

(... Тука доаѓа заглавието на датотеката и дефиницијата на формата TForm1 и нејзиниот примерок Form1)

(Видете го целиот извор овде)

процедура TForm1.Button1Click (Испраќач: TObject ) ;

започне

(Ја дефинираме портата и го стартуваме серверот)

ServerSocket1.Port := 1025;

(Методот Insert вметнува низа во низата на одредената позиција)

Memo2.Lines .Вметни (0 ,"Серверот стартува" );

ServerSocket1.Open ;

крај ;

процедура TForm1.Button2Click (Испраќач: TObject ) ;

започне

(Сопрете го серверот)

ServerSocket1.Active := Неточно;

Memo2.Lines .Вметни (0 ,"Серверот е запрен" ) ;

крај ;

процедура TForm1.ServerSocket1Listen(Испраќач: TObject ;

Сокет: TCustomWinSocket);

започне

(Тука серверот „слуша“ на штекерот за клиенти)

Memo2.Lines .Insert (0 ,Listening on port " +IntToStr (ServerSocket1.Port ) );

крај ;

процедура TForm1.ServerSocket1Accept(Испраќач: TObject ;

Сокет: TCustomWinSocket);

започне

(Тука серверот го прифаќа клиентот)

Memo2.Lines .Вметни (0 ,Прифатено е поврзување со клиентот“ );

крај ;

процедура TForm1.ServerSocket1ClientConnect(Испраќач: TObject ;

Сокет: TCustomWinSocket);

започне

(Тука клиентот се поврзува)

Memo2.Lines .Вметни (0 ,„Клиент поврзан“ ) ;

крај ;

процедура TForm1.ServerSocket1ClientDisconnect(Испраќач: TObject ;

Сокет: TCustomWinSocket);

започне

(Тука клиентот се исклучува)

Memo2.Lines .Вметни (0 ,"Клиентот е исклучен" );

крај ;

процедура TForm1.ServerSocket1ClientError (Испраќач: TObject ;

Сокет: TCustomWinSocket; ErrorEvent: TErrorEvent;

var Код на грешка: Цел број);

започне

(Се појави грешка - испечатете го неговиот код)

Memo2.Lines .Вметни (0 ,"Грешка на клиентот. Код = " +IntToStr (Код на грешка) ) ;

крај ;

процедура TForm1.ServerSocket1ClientRead(Испраќач: TObject ;

Сокет: TCustomWinSocket);

започне

(Добиена е порака од клиентот - ја прикажуваме во Memo1)

Memo2.Lines .Вметни (0 , „Порака добиена од клиентот“) ;

Memo1.Lines .Insert (0 ,"> " +Socket.ReceiveText ) ;

крај ;

процедура TForm1.ServerSocket1ClientWrite(Испраќач: TObject ;

Сокет: TCustomWinSocket);

започне

(Сега можете да испраќате податоци до штекерот)

Memo2.Lines .Вметни (0 ,"Сега може да пишува во штекер" );

крај ;

процедура TForm1.ServerSocket1GetSocket (Испраќач: TObject ; Сокет: Цел број ;

var ClientSocket: TServerClientWinSocket);

започне

Memo2.Lines .Вметни (0 , "Get socket" ) ;

крај ;

процедура TForm1.ServerSocket1GetThread(Испраќач: TObject ;

ClientSocket: TServerClientWinSocket;

varSocketThread: TServerClientThread) ;

започне

Memo2.Lines .Insert (0 ,Get Thread) ;

крај ;

процедура TForm1.ServerSocket1ThreadEnd (Испраќач: TObject ;

започне

Memo2.Lines .Вметни (0 ,„Крај на конец“ ) ;

крај ;

процедура TForm1.ServerSocket1ThreadStart(Испраќач: TObject ;

Тема: TServerClientThread) ;

започне

Memo2.Lines .Вметни (0 ,"Почеток на нишка" ) ;

крај ;

процедура TForm1.Button3Click (Испраќач: TObject ) ;

var i: Цел број ;

започне

(Испратете порака на СИТЕ клиенти од Edit1)

за i:= 0 до ServerSocket1.Socket.ActiveConnections -1 започнуваат

ServerSocket1.Socket .Поврзувања[i] .SendText(Edit1.Text) ;

крај ;

Memo1.Lines .Insert(0,"< " +Edit1.Text ) ;

крај ;

Понатаму, повеќе нема да разгледуваме примери, туку методи на работа со TServerSocket.
Техники за работа со TServerSocket (и само сокети)
Складирање единствени податоци за секој клиент.
Сигурно, ако вашиот сервер ќе опслужува многу клиенти, тогаш ќе треба да складирате некои информации за секој клиент (име, итн.), и со врзување на овие информации за сокетот на овој клиент. Во некои случаи, да се прави сето ова рачно (врзување на рачката на штекерот, низи клиенти, итн.) не е многу погодно. Затоа, за секој штекер има посебно својство - Податоци. Всушност, податоците се само покажувач. Затоа, кога пишувате податоци за клиентот на овој имот, бидете внимателни и следете ги правилата за работа со покажувачи (распределба на меморија, заклучување на типот итн.)!
Испраќање датотеки преку приклучок.
Овде ќе разгледаме испраќање датотеки преку сокет (на барање на JINX) :-). Значи, како да испратите датотека преку приклучок? Многу едноставно! Треба само да ја отворите оваа датотека како пренос на датотеки (TFileStream) и да ја испратите преку сокет (SendStream)! Да го погледнеме ова со пример:

(Се испраќа датотека преку штекер)

процедура SendFileBySocket(име на датотека: низа ) ;

var srcfile: TFileStream;

започне

(Отвори име на датотека)

Srcfile:= TFileStream.Create (име на датотека,fmOpenRead) ;

(Испратете го на првиот поврзан клиент)

ServerSocket1.Socket .Поврзувања [ 0 ] .SendStream(srcfile) ;

(Затворете ја датотеката)

Srcfile.Free;

крај ;

Треба да се напомене дека методот SendStream се користи не само од серверот, туку и од клиентот (ClientSocket1.Socket.SendStream(srcfile))
Зошто може неколку блокови да се комбинираат во еден за време на преносот?
Ова го бара и JINX :-). Голема благодарност до него за ова! Значи, прво, треба да се забележи дека податоците испратени преку штекерот не само што можат да се комбинираат во еден блок, туку и да се поделат во неколку блокови. Факт е дека сокетот е нормален поток, но за разлика од, да речеме, пренос на датотеки (TFileStream), тој ги пренесува податоците побавно (разбирате - мрежата, ограничениот сообраќај итн.). Затоа две команди:
ServerSocket1.Socket.Connections.SendText("Здраво, ");
ServerSocket1.Socket.Connections.SendText("свет!");
се целосно идентични со една команда:
ServerSocket1.Socket.Connections.SendText("Здраво, свет!");
И затоа, ако испратите датотека, да речеме, 100 Kb, преку штекерот, тогаш лицето на кое сте го испратиле овој блок ќе добие неколку блокови со големини кои зависат од сообраќајот и оптоварувањето на линијата. Покрај тоа, димензиите не мора да бидат исти. Следи дека за да примите датотека или други големи податоци, треба да примате блокови од податоци и потоа да ги комбинирате во една целина (и да зачувате, на пример, во датотека). Одлично решение за овој проблем е истиот проток на датотеки - TFileStream (или поток во меморијата - TMemoryStream). Можете да примате честички на податоци од приклучокот преку настанот OnRead (OnClientRead), користејќи го универзалниот метод ReceiveBuf. Можете да ја одредите големината на примениот блок користејќи го методот ReceiveLength. Можете исто така да користите приклучок за пренос (видете ја статијата TClientSocket). И еве мал пример (приближно):

(Примајте датотека преку штекер)

процедура TForm1.ClientSocket1Read(Испраќач: TObject ;

Сокет: TCustomWinSocket);

varl: Цел број ;

Буф: ПХар;

Src: TFileStream;

започне

(Ја пишуваме во l големината на примениот блок)

L:= Socket.ReceiveLength ;

(Нарачуваме меморија за баферот)

GetMem(buf,l+1);

(Го запишуваме примениот блок во баферот)

Socket.ReceiveBuf(buf,l) ;

(Отворете привремена датотека за пишување)

Src:= TFileStream.Create("myfile.tmp" ,fmOpenReadWrite) ;

(Ставете ја позицијата на крајот од датотеката)

Src.Seek(0,soFromEnd) ;

(Напиши бафер во датотека)

Src.WriteBuffer(buf,l) ;

(Затворете ја датотеката)

Src.Free ;

(Ослободување на меморијата)

FreeMem (buf) ;

крај ;

Како да следите штекер
Ова прашање е сложено и бара долго разгледување. Засега, само ќе забележам дека секогаш можете да го следите штекерот создаден од вашата програма :-). Сокетите (како и повеќето објекти во Windows) имаат своја рачка (рачка), напишана во својството Handle. Значи, откако го научивте овој дескриптор, можете слободно да контролирате кој било сокет (дури и оние создадени од туѓа програма)! Сепак, најверојатно ќе треба да ги користите функциите на WinAPI Sockets за да го надгледувате туѓиот сокет.
Епилог
Оваа статија ги прикажува основните трикови за работа со компонентата TServerSocket во Delphi и неколку општи трикови за комуникација преку сокети. Ако имате какви било прашања - испратете ми ги на е-пошта: [заштитена е-пошта], и уште подобро - пишете во форумот на оваа страница (Делфи. Општи прашања), за да можат другите корисници да го видат вашето прашање и да се обидат да одговорат!
Карик Николај (Нитро). Московскиот регион, Жуковски

Додадов мрежна поддршка. Тоа е создаден посебен сервер и посебен клиент. Поентата е дека серверот за апликации работи, корисникот го стартува клиентот и го внесува барањето во корисникот: Москва Тверскаја 6. Потоа серверот го обработува барањето, добива резултати од пребарувањето од Yandex.Maps и ја испраќа добиената слика до клиентот, а потоа клиентот во компонентата TMap прикажува дел од оваа карта што одговара на барањето на корисникот. Како резултат на тоа, корисникот може да го скалира, да го зачува итн.

Затоа, во оваа статија сакам да ви кажам како ги имплементирав клиентот и серверот. Го направив ова со помош на TClientSocket и TServerSocket, во оваа статија детално ќе ги разгледаме методите што ги користев во мојот проект.

Прво, да видиме како овие компоненти може да се инсталираат во IDE. Ако користите Delphi 7 IDE, тогаш стандардно овие компоненти се присутни, но, за жал, тие не се инсталирани, но ова не е проблем. Треба само да го отвориме Delphi и да инсталираме.

За да го направите ова, извршете ја командата Component-Install Packages… и во прозорецот што се појавува, кликнете на копчето Додај. После тоа, мора да ја наведете патеката до датотеката dclsockets70.bpl, која обично се наоѓа во папката BIN стандардно. После тоа, треба да кликнете на копчето ОК. Сè, вашите компоненти треба да се појават на картичката Интернет (TClientSocket и TServerSocket).

Во проектот ја започнав целата работа, со минимален развој на серверот. Прво, ја инсталирав компонентата TServerSocket на формуларот. И со кликнување на копчето Start server, поставете почетните поставки, за да го иницијализирате:

сервер. Порт := ФормСерверПоставување. SpinEditPort. вредност; //наведете серверска портасервер. Активно := Точно; //активирај го Серверот. отворено; ifServer. Активни потоа започнете //прикажи порака дека серверот е вклучен и работикрај ; …….. //прикажи грешка ако серверот не е стартуван

За да го иницијализирам серверот на мојата машина, поставив само бесплатна порта (која не е окупирана од други апликации) и ја активирав.

Во принцип, тоа е се, за работа ми беше доволно што работи серверот и можев да ги обработам барањата на клиентите што тие ги испраќаат.

Со цел да добијам листа на клиенти кои се поврзуваат со серверот и понатаму да работам со нив, ја инсталирав компонентата TCheckListBox на формуларот и на настанот OnclientConnect од компонентата TServerSocket, го напишав следниов код:

процедура TFormServer. ServerClientConnect (Испраќач: TObject; Сокет: TCustomWinSocket) ; започне //мониторирајте ја врската со клиентот richeditlog. SelAttributes . Боја :=clЗелена; richeditlog. SelAttributes . Стил := [fsBold] ; CheckListClient. Предмети . Додај (Socket.RemoteHost); richeditlog. Линии. Додај ("[" + TimeToStr (Time ) + "] Клиент е поврзан: " + Socket. RemoteHost ) ; // додадете во листата клиентот што се поврзал richeditlog. Изведете (WM_VSCROLL, SB_BOTTOM, 0); крај ;

Односно, во списокот ги додавам имињата на оние клиенти кои се поврзуваат со серверот за да добијам дополнителни информации за нив.

На пример, можете да добиете детални информацииза клиентот:

процедура TFormInfoClient. FormShow(Испраќач: TObject) ; започне // печати информации за клиентотнатпис: = "Информации за клиентите:"+ формулар сервер. CheckListClient. Ставки [FormServer. CheckListClient. ItemIndex] ; локално име. Наслов:= Формсервер. Сервер. штекер. Врски [FormServer. CheckListClient. ItemIndex] . LocalHost ; локален домаќин. Наслов:= Формсервер. Сервер. штекер. Врски [FormServer. CheckListClient. ItemIndex] . Локална адреса; локален пристаниште. Наслов := IntToStr (FormServer. Server. Socket. Connections [FormServer. CheckListClient. ItemIndex]. LocalPort); далечинско име. Наслов:= ФормСервер. Сервер. штекер. Врски [FormServer. CheckListClient. ItemIndex] . далечински домаќин; далечински домаќин. Наслов:= ФормСервер. Сервер. штекер. Врски [FormServer. CheckListClient. ItemIndex] . Далечинска адреса; далечински извештај. Наслов := IntToStr (FormServer. Server. Socket. Connections [FormServer. CheckListClient. ItemIndex]. RemotePort); крај ;

Можете да ги добиете следните податоци:

  • локално име
  • Локална адреса
  • локално пристаниште
  • далечинско име
  • далечинска адреса
  • далечинска порта

Добивам информации за клиентот користејќи го овој код, кој го избрав во списокот на компонентата TCheckListBox.

Како што можете да видите, нема ништо комплицирано, за да испратите порака до клиентот, можете да го користите следниов код:

ВО квадратни загради, укажувам на кој клиент ќе ја испратиме пораката (тоа е еднакво на избраниот клиент во компонентата TCheckListBox), наведувам #порака# во пораката - што значи дека ова е нормална порака од серверот, која едноставно треба да се прикаже во прозорецот.

За да добиеме порака од клиентот до серверот, потребен ни е настанот OnClientRead од компонентата TServerSocket и текстуална променлива во која ќе го запишеме барањето испратено од клиентот.

процедура TFormServer. ServerClientRead(Испраќач: TObject; Сокет: TCustomWinSocket) ; var query: Низа ; започне //прими барање од клиентот за картичкатаобидете се со барање:= Сокет. ReceiveText ; if pos („прашање“, барање)<>0 потоа започнете //барање од Yandex или Гугл координатикартички по барање на клиентоткрај ; //ако е само порака од клиентот, тогаш прикажете јаако е („#порака#“, барање)<>0 потоа започне крајот; ……

Од овој код, можете да видите дека клиентот може да испрати и редовна порака до серверот и барање за картичка, како што се: Москва, Тверскаја, 6.

За да го направам ова, треба да одредам каде е вообичаената порака и каде точно е барањето за добивање на картичката, за да може серверот да ја обработи во иднина. Во овој случај, на самиот почеток, ги додавам следните идентификатори на пораките на клиентот:

  • #порака#
  • #прашање#

Ако идентификаторот #порака# е присутен на почетокот на пораката на клиентот, тогаш серверот ќе ја препознае како нормална порака од клиентот. Ако идентификаторот #query# е присутен на почетокот на пораката, тоа значи дека клиентот испратил барање да добие картичка.

Исто така, клиентот може да се исклучи од серверот во секое време, исто така треба да го следиме ова за да го отстраниме од општата листа на клиенти поврзани на серверот. За да го направите ова, изберете ја компонентата TServerSocket и напишете го следниов код на настанот OnClientDisconnect:

процедура TFormServer. ServerClientDisconnect (Испраќач: TObject ; Сокет: TCustomWinSocket) ; var i: цел број ; започнете да се обидувате //мониторирајте го исклучувањето на клиентот richeditlog. SelAttributes . Боја :=clЦрвена; richeditlog. SelAttributes . Стил := [fsBold] ; за јас := 0 до серверот. штекер. ActiveConnections - 1 започнува ако Сервер. штекер. Врски[i]. Рачка = сервер. штекер. Врски[i]. Ракувајте и започнете со RichEditLog. Линии. Додај ("[" + TimeToStr (Time ) + "] Клиентот е исклучен: " + Socket. RemoteHost ) ; CheckListClient. Предмети . Избриши(i) ; richeditlog. Изведете (WM_VSCROLL, SB_BOTTOM, 0); крај ; крај ; конечно //-//-//-//-//-// крај ; крај ;

Ги разгледуваме сите клиенти што ги имаме во списокот и ако не најдеме, тогаш го отстрануваме од компонентата TCheckListBox, што значи дека клиентот во неговата апликација кликнал на копчето Исклучи.




Врв