Delphi розеткасының қосылымын тексеру. Delphi. Delphi-де сокеттік бағдарламалау. Күрделі деректерді жіберу және қабылдау

Розеткалар (розеткадан (ағыл.) - қосқыш, розетка) болып табылады бағдарламалық интерфейс, ол процестер арасында ақпарат алмасуды қамтамасыз етеді.

Желідегі розеткалық байланыстың негізгі артықшылықтарының бірі оның икемділігі болып табылады. Розеткалармен жұмыс істеудің негізгі принципі басқа компьютерге байттар тізбегін жіберу болып табылады, ол қарапайым мәтіндік хабарлама немесе файл болуы мүмкін.

Розеткалардың екі түрін ажырату маңызды: клиент розеткалары , Және сервер розеткалары .

Delphi-де розеткалардың «клиент» типімен жұмыс істеу үшін компонент бар TClientSocket, компонентті пайдаланып «сервер» ұяшықтарымен жұмыс істеуге болады TServerSocket.

Компоненттерді орнату

Көбінесе TServerSocket және TClientSocket компоненттері стандартты Delphi орнату пакетіне кірмейді, бірақ оларды бөлек орнатуға болады.

«Интернет» құрамдастары қойындысына өтіп, онда TServerSocket және TClientSocket құрамдастарының бар-жоғын тексеріңіз, егер жоқ болса, оларды орнатыңыз. «Компонент/Орнату пакеттері» мәзіріне өтіп, «Қосу» түймесін басыңыз. Ашылған диалогтық терезеде «dclsocketsXX.bpl» файлын табу керек (ол Delphi бар қалтада орналасқан bin қалтасында орналасқан), мұнда ХХ – сіздің Delphi-дің сандық нұсқа нөмірі. Файлды тауып, Ашу түймесін басыңыз, содан кейін Бумаларды орнату терезесінде OK түймесін басыңыз. Енді «Интернет» қойындысында екі компонент пайда болды - TServerSocket және TClientSocket.

Клиент сокеттерімен жұмыс істеу (tClientSocket)

1) Порт және хост сипаттарын анықтау.Сәтті қосылым сипаттары үшін портЖәне Хост TClientSocket компонентіне кейбір мәндер тағайындалуы керек. Порт сипатында қосылу үшін порт нөмірін көрсету керек (1 - 65535, бірақ 1001 - 65535 ауқымынан алған дұрыс, себебі 1000-ға дейінгі сандар жүйелік қызметтерде болуы мүмкін).

Хост- қосылатын компьютердің хост атауы немесе IP мекенжайы. Мысалы, rus.delphi.com немесе 192.128.0.0.

2) Розетканың ашылуы.Біз розетканы бір компьютерден екінші компьютерге берілетін таңбалар кезегі ретінде қарастырамыз. Әдісті шақыру арқылы розетканы ашуға болады ашық(TClientSocket компоненті) немесе мән тағайындау арқылы Расмүлік Белсенді. Бұл жерде қосылым сәтсіз болған жағдайда ерекшелік өңдеушісін қою пайдалы болар еді.

3) Мәліметтерді жіберу/қабылдау.

4) Розетканың жабылуы.Деректер алмасуды аяқтағаннан кейін әдісті шақыру арқылы розетканы жабу керек жабыққұрамдас TClientSocketнемесе мән тағайындау арқылы Жалғанмүлік Белсенді.

TClientSocket компонентінің негізгі қасиеттері

Розетканың ашық немесе жабық екенін көрсететін көрсеткіш. Ашылған – шын мән, жабық – жалған мән. Жазу үшін қол жетімді.

Қосылатын хост аты

Қосылатын компьютердің IP мекенжайы. Хосттан айырмашылығы, мұнда тек IP мекенжайын көрсетуге болады. Айырмашылық мынада, егер Хостта нақты компьютер атауы болса, онда IP DNS жүйесінен сұралады

Қосылатын компьютердің порт нөмірі (1-65535)

ClientType

Деректерді тасымалдау түрін қамтиды:

ctBlocking- синхронды беру ( OnReadЖәне OnWriteжұмыс істемейді). Синхронды қосылым түрі ағынды деректер алмасу үшін қолайлы;

ctNonBlocking- асинхронды беру (мәліметтерді жіберу/қабылдау оқиғалардың көмегімен жүзеге асырылуы мүмкін OnReadЖәне OnWrite)

TClientSocket компонентінің негізгі әдістері

Розетка ашады (белсенді сипатты True мәніне орнату)

Розетканы жабады (белсенді сипатты False мәніне орнату)

TClientSocket компонентінің негізгі оқиғалары

Қосылуда

Байланыс орнатылған кезде пайда болады. Өңдеушіде авторизацияны немесе деректерді жіберуді/алуды бастай аласыз

Қосылуда

Қосылған кезде де пайда болады. OnConnect-тен айырмашылығы қосылым әлі орнатылмаған. Көбінесе, мысалы, күйді жаңарту үшін қолданылады

Қосылуды ажырату

Оқиға розетка бағдарламамен, қашықтағы компьютермен немесе ақаулық салдарынан жабылған кезде орын алады

Оқиға қате бойынша көтеріледі. Розетка ашылып жатқанда, бұл оқиға қатені анықтауға көмектеспейді. Windows жүйесінен қате туралы хабарды болдырмау үшін, ашық мәлімдемелерді "" ішіне қою арқылы ішкі ерекшеліктерді өңдеу туралы қамқорлық жасаған дұрыс. көріңіз.. қоспағанда »

OnLookup

Оқиға DNS жүйесінен IP мекенжайын алуға әрекет жасағанда орын алады

Оқиға қашықтағы компьютер кейбір деректерді жіберген кезде орын алады. OnRead шақыру кезінде алынған деректерді өңдеуге болады

Оқиға сіздің бағдарламаңызға деректерді ұяшыққа жазуға рұқсат етілгенде көтеріледі

Бұл мақалада негізгі қасиеттер мен функциялар қарастырылады Delphi компоненттері: TClientSocket және TServerSocket – TCP\IP протоколы арқылы желімен жұмыс істеу үшін қолданылады.

Назар аударыңыз! Delphi-дің 6.0-ден жоғары нұсқасын пайдалансаңыз, алдымен Sockets Components орнатуыңыз керек, Delphi-дің барлық нұсқаларында бұл келесідей орындалады:

  • Бумаларды орнату… диалогтық терезесіне өтіңіз: (Негізгі мәзір) Құрамдас -> Бумаларды орнату;
  • «Қосу...» түймесін басыңыз, содан кейін біз сіздің Delphi қалтаңыздың Bin қалтасын табамыз (мысалы: C:\Program Files\Borland\Delphi 7\bin немесе C:\Program Files\Embarcadero\RAD Studio\7.0\Bin);
  • Табылған қалтада біз файлды іздеп жатырмыз dclsockets [мұнда нөмірлер].bpl, OK түймесін басыңыз;
  • Біз қуаныштымыз, өйткені қазір бізде Интернет қойындысының компоненттер тақтасының қойындысында екі тамаша құрамдас TServerSocket және TClientSocket бар.

Кез келген желілік қосымшаларды әзірлеу кезінде әзірлеу әрқашан серверден басталады (әрине, егер сізде команда болса, фронт-end дизайнерлері клиентте жұмыс істей алады). Серверді іске асыру үшін таңқаларлық, сізге TServerSocket пайдалану керек.

Негізгі қасиеттері:

  • Белсенді– логикалық түр өрісі, шын мәніне орнатылғанда – сервер іске қосылады, оны арнайы мәндерді тағайындау арқылы да, ServerSocket1.Open (… Active:=true;) немесе ServerSocket1.Close (… Active:=false) шақыру арқылы да пайдалануға болады. функциялары.
  • порт- сервер тыңдайтын (клиенттерді қабылдайтын) порт, ауқымдағы жүйедегі басқа серверлер иеленбейтін кез келген мән бүтін сан.

Негізгі оқиғалар:

  • OnListen- сервер тыңдау режиміне орнатылғанда шақырылады, сервердің нақты басталу уақытын анықтау қажет болғанда пайдаланылуы мүмкін.
  • OnClientRead– клиенттен мәліметтерді алу сәтінде шақырылады.
  • OnClientError
  • OnClientConnect- Серверге жаңа клиент қосылғанда шақырылады.
  • OnClientDisconnect- оқиғаға қарама-қарсы оқиға, OnClientConnect

әрбір оқиға функциясының төлсипаты болады Розетка: TCustomWinSocket, біз кіретін ұяшық нысанының көрсеткіші осы сәтжұмыс, егер бізге бір нәрсеге жауап беру немесе оқиғаны тудырған клиентпен бірдеңе істеу қажет болса, біз осы нақты нысанды пайдалануымыз керек, қалған барлық жағдайларда біз қолданамыз ServerSocket1.Socket, жағдай клиент компонентімен ұқсас.

Тек оқуға арналған қасиеттер мен функциялар:

  • – белсенді қосылымдар санын қайтарады.
  • ServerSocket1.Socket.Connections– 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 типті мәтіндік хабарламаны жібереді жол.

TClientSocket компоненті үшін бәрі дерлік бірдей, тек керісінше + сервер мен клиент арасындағы негізгі визуалды айырмашылық, жүйедегі серверді 1-ден 1-ге дейін порт мәніне қосуға болады, тек ЖЖҚ сізді санмен шектейді. клиенттер.

Негізгі қасиеттері:

  • Белсенді– логикалық түр өрісі, шын мәніне орнатылғанда – клиент серверге қосылуға тырысады, оны арнайы мәндерді тағайындау арқылы да, ClientSocket1.Open (… Active:=true;) немесе ClientSocket1.Close (… Active) шақыру арқылы да пайдалануға болады. :=жалған) функциялары .
  • порт– клиент серверге қосыла алатын порт, ауқымдағы кез келген мән бүтін сан.
  • Мекенжай– сервер түрінің IPv4 мекенжайы жолклиент қосылатын 255.255.255.255 үлгісі.

Негізгі оқиғалар:

  • OnRead– солтүстіктен деректер түскен кезде шақырылады.
  • OnError- Деректерді тасымалдау кезінде қате орын алған кезде шақырылады.
  • Қосылуда- Клиент серверге қосылған кезде шақырылады.
  • Қосылуды ажырату- оқиғаға қарама-қарсы оқиға, Қосылуда, клиент серверден ажыратылған кезде шақырылады.

Тек оқуға арналған қасиеттер мен функциялар:

  • ClientSocket1.Socket.SendText() жол
  • Socket.LocalHost– желідегі клиенттің атын қайтарады.
  • Socket.LocalAddress– клиенттің IP мекенжайын қайтарады.
  • Socket.RemoteHost– желідегі сервердің атын қайтарады.
  • Socket.RemoteAddress– сервердің IP мекенжайын қайтарады.
  • Socket.ReceiveText– серверден алынған мәтіндік хабарламаны қайтарады, содан кейін ол буферді тазартады, 1 қабылдау үшін тек 1 рет пайдалануға болады.
  • Socket.SendText(Мәтін)– серверге Text түріндегі мәтіндік хабарламаны жібереді жол.

Берілген ақпарат қанағаттандыратын шағын серверлік чатты жүзеге асыру үшін жеткілікті техникалық тапсырма: internet_sockets.doc (Word Doc 97-2003, 26,5 Kb).

Бұл мақала 2010 жылдың 10 қазаны, жексенбі күні сағат 1:24 бөлімінде жазылған. Сіз мақалаға түсініктемелердің жаңартуларына жазыла аласыз -. Сен істе аласың


Кіріспе


Бұл мақала Borland Delphi жүйесінде розеткаға негізделген клиент/сервер қосымшаларын жасау туралы («розеткалар» - ұялар). Розеткалар тақырыбына арналған алдыңғы мақаладан айырмашылығы, мұнда біз серверлік қосымшаларды құруды талдаймыз.

Жеке клиенттік және серверлік қосымшалардың қатар өмір сүруі үшін бірнеше компьютердің болуы міндетті емес екенін бірден атап өткен жөн. Серверді де, клиентті де бір уақытта іске қосуға болатын біреуі ғана болса жеткілікті. Бұл жағдайда қосылатын компьютердің атауы ретінде хост атауын пайдалану керек. жергілікті хостнемесе IP мекенжайы - 127.0.0.1 .

Сонымен, теориядан бастайық. Егер сіз табанды тәжірибеші болсаңыз (және көзіңізбен ешқандай алгоритмді көре алмасаңыз), онда бұл бөлімді өткізіп жіберуіңіз керек.

Сокет серверінің алгоритмі


Розетка сервері не істейді?.. Ол қалай жұмыс істейді?.. Розетка протоколына негізделген сервер бір уақытта көптеген клиенттерге қызмет көрсетуге мүмкіндік береді. Сонымен қатар, олардың санына шектеуді өзіңіз белгілей аласыз (немесе әдепкі бойынша бұл шектеуді толығымен алып тастаңыз). Әрбір қосылған клиент үшін сервер жеке ұяшықты ашады, ол арқылы клиентпен деректер алмасуға болады. Сондай-ақ тамаша шешім - әрбір қосылым үшін бөлек процесті (Thread) жасау.

Төменде Delphi қолданбаларында розетка серверінің жұмысының мысалы келтірілген:

Схеманы толығырақ талдап көрейік:

  • Порт және ServerType сипаттарын анықтау - клиенттердің серверге қалыпты қосылуы үшін сервер пайдаланатын порт клиент пайдаланатын портқа дәл сәйкес келуі керек (және керісінше). ServerType қасиеті қосылым түрін анықтайды (толығырақ ақпаратты төменде қараңыз);
  • розетканың ашылуы - Розетка мен көрсетілген портты ашу. Мұнда клиенттердің қосылуын күтудің автоматты басталуы орындалады ( Тыңда);
  • Клиентті қосу және онымен деректер алмасу - мұнда клиент онымен байланысады және деректермен алмасады. Бұл кезең туралы толығырақ осы мақалада және розеткалар туралы мақалада (клиент жағы) кейінірек біле аласыз;
  • Клиентті өшіру - Мұнда клиент ажыратылады және оның серверге розеткалық қосылымы жабылады;
  • Сервер мен ұяшықты жабу - Әкімшінің бұйрығымен сервер өз жұмысын тоқтатады, барлық ашық розетка арналарын жауып, клиенттік қосылымдарды күтуді тоқтатады.

Айта кету керек, 3-4 тармақтар бірнеше рет қайталанады, яғни. бұл элементтер әрбір жаңа клиенттік қосылым үшін орындалады.

Ескерту : Қазіргі уақытта Delphi-де розеткаларға қатысты құжаттама өте аз, сондықтан бұл тақырыпты мүмкіндігінше тереңірек зерттегіңіз келсе, мен сізге 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 - клиент розетка арнасынан ажыратылғанда пайда болады;
OnClientError - ағымдағы операция сәтсіз болғанда пайда болады, яғни. Қате орын алды;
OnClientRead - клиент кейбір деректерді серверге жіберген кезде пайда болады. Бұл деректерге өткен параметр арқылы қол жеткізуге болады Розетка: TCustomWinSocket;
OnClientWrite - сервер розеткадағы клиентке деректерді жібере алатын кезде пайда болады;
OnGetSocket - осы оқиғаның өңдеушісінде параметрді өңдеуге болады ClientSocket;
OnGetThread - осы оқиғаның өңдеушісінде параметрді орнату арқылы әрбір жеке клиент арнасы үшін бірегей процесті (Thread) анықтауға болады. SocketThreadқажетті қосалқы тапсырма TServerClientThread;
OnThreadStart , OnThreadEnd - сәйкесінше қосалқы тапсырма (процесс, Thread) басталғанда немесе тоқтаған кезде пайда болады;
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(Sender: TObject); БАСТА (Біз портты анықтаймыз және серверді бастаймыз) ServerSocket1.Port:= 1025; (Insert әдісі жолды массивке көрсетілген орында кірістіреді) Memo2.Lines.Insert(0,"Сервер іске қосылды"); ServerSocket1.Open; Соңы; процедура TForm1.Button2Click(Sender: TObject); БАСТА (Серверді тоқтату) ServerSocket1.Active:= False; Memo2.Lines.Insert(0,"Сервер тоқтады"); Соңы; процедурасы TForm1.ServerSocket1Listen(Жіберуші: TObject; Socket: TCustomWinSocket); БАСТА (Мұнда сервер клиенттерге арналған ұяшықта «тыңдайды») Memo2.Lines.Insert(0,"Портта тыңдау "+IntToStr(ServerSocket1.Port)); Соңы; процедура TForm1.ServerSocket1Accept(Жіберуші: TObject; Socket: TCustomWinSocket); БАСТА (Мұнда сервер клиентті қабылдайды) Memo2.Lines.Insert(0,"Клиент қосылымы қабылданды"); Соңы; процедура TForm1.ServerSocket1ClientConnect(Жіберуші: TObject; Socket: TCustomWinSocket); БАСТА (Мұнда клиент қосылады) Memo2.Lines.Insert(0,"Клиент қосылған"); Соңы; процедура TForm1.ServerSocket1ClientDisconnect(Жіберуші: TObject; Socket: TCustomWinSocket); БАСТА (Мұнда клиент ажыратылады) Memo2.Lines.Insert(0,"Клиент ажыратылды"); Соңы; procedure TForm1.ServerSocket1ClientError(Жіберуші: TObject; Socket: TCustomWinSocket; ErrorEvent: TERrorEvent; var ErrorCode: Integer); БАСТА (Қате орын алды - оның кодын басып шығарыңыз) Memo2.Lines.Insert(0,"Клиент қатесі. Код = "+IntToStr(ErrorCode)); Соңы; процедура TForm1.ServerSocket1ClientRead(Жіберуші: TObject; Socket: TCustomWinSocket); БАСТА (Клиенттен хабарлама алынды - біз оны Memo1-де көрсетеміз) Memo2.Lines.Insert(0,"Клиенттен хабарлама алынды"); Memo1.Lines.Insert(0,"> "+Socket.ReceiveText); Соңы; процедурасы TForm1.ServerSocket1ClientWrite(Жіберуші: TObject; Socket: TCustomWinSocket); БАСТА (Енді деректерді ұяшыққа жіберуге болады) Memo2.Lines.Insert(0,"Енді ұяшыққа жазуға болады"); Соңы; процедура TForm1.ServerSocket1GetSocket(Жіберуші: TObject; Socket: Integer; var ClientSocket: TServerClientWinSocket); begin Memo2.Lines.Insert(0,"Get rozetka"); Соңы; procedure TForm1.ServerSocket1GetThread(Жіберуші: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread); begin Memo2.Lines.Insert(0, "Жіпті алу"); Соңы; процедура TForm1.ServerSocket1ThreadEnd(Жіберуші: TObject; Thread: TServerClientThread); begin Memo2.Lines.Insert(0,"Жіп соңы"); Соңы; процедура TForm1.ServerSocket1ThreadStart(Жіберуші: TObject; Thread: TServerClientThread); begin Memo2.Lines.Insert(0,"Жіптің бастауы"); Соңы; процедура TForm1.Button3Click(Sender: TObject); var i: Integer; БАСТА (Барлық клиенттерге Edit1 хабарламасын жіберіңіз) i:= 0 үшін ServerSocket1.Socket.ActiveConnections-1 басталады ServerSocket1.Socket.Connections[i].SendText(Edit1.Text); Соңы; Memo1.Lines.Insert(0,"

TServerSocket (және жай розеткалармен) жұмыс істеу әдістері


Әрбір клиент үшін бірегей деректерді сақтау.


Әрине, егер сіздің серверіңіз көптеген клиенттерге қызмет көрсететін болса, онда сіз әрбір клиент үшін кейбір ақпаратты (аты және т.б.) сақтауыңыз керек және бұл ақпаратты осы клиенттің ұясына байланыстыру керек. Кейбір жағдайларда мұның бәрін қолмен жасау (розетка тұтқасына, клиенттердің массивтеріне және т.б. байланыстыру) өте ыңғайлы емес. Сондықтан әрбір розетка үшін арнайы қасиет бар - Деректер. Шын мәнінде, Деректер тек көрсеткіш. Сондықтан, осы сипатқа клиент деректерін жазғанда абай болыңыз және көрсеткіштермен жұмыс істеу ережелерін (жадты бөлу, типті қорытындылау және т.б.) орындаңыз!

Файлдарды ұяшық арқылы жіберу.


Мұнда файлдарды ұяшық арқылы жіберуді қарастырамыз (JINX сұрағандай) :-). Сонымен, файлды ұяшық арқылы қалай жіберуге болады? Өте оңай! Бұл файлды файл ағыны (TFileStream) ретінде ашып, оны ұяшық (SendStream) арқылы жіберу керек! Мұны мысалмен қарастырайық:

Бұл әдіс екенін атап өткен жөн жіберу ағынысервер ғана емес, сонымен қатар клиент ( ClientSocket1.Socket.SendStream(srcfile))

Неліктен тасымалдау кезінде бірнеше блоктарды бір блокқа біріктіруге болады?


Мұны JINX :-) де сұрайды. Бұл үшін оған көп рахмет! Сонымен, біріншіден, розетка арқылы жіберілетін деректерді бір блокқа біріктіріп қана қоймай, бірнеше блоктарға бөлуге болатындығын атап өткен жөн. Мәселе мынада, розетка қалыпты ағын болып табылады, бірақ, айталық, файлдық ағыннан (TFileStream) айырмашылығы, ол деректерді баяу тасымалдайды (сіз түсінесіз - желі, шектеулі трафик және т.б.). Сондықтан екі команда:
ServerSocket1.Socket.Connections.SendText("Сәлеметсіз бе,");
ServerSocket1.Socket.Connections.SendText("әлем!");
бір пәрменге толығымен ұқсас:
ServerSocket1.Socket.Connections.SendText("Сәлем, әлем!");

Сондықтан, егер сіз розетка арқылы файлды, айталық, 100 Кб жіберсеңіз, онда сіз осы блокты жіберген адам трафик пен желі жүктемесіне байланысты өлшемдері бар бірнеше блоктарды алады. Оның үстіне өлшемдердің бірдей болуы міндетті емес. Бұл файлды немесе кез келген басқа деректерді алу үшін үлкен өлшем, Деректер блоктарын алып, оларды бір бүтінге біріктіру керек (және, мысалы, файлға сақтау). Бұл мәселенің тамаша шешімі - бірдей файл ағыны - TFileStream (немесе жадтағы ағын - TMemoryStream). Сіз әмбебап әдісті пайдаланып OnRead (OnClientRead) оқиғасы арқылы розеткадан деректер бөлшектерін ала аласыз. ReceiveBuf. Әдістің көмегімен алынған блоктың өлшемін анықтауға болады Қабылдау ұзындығы. Сондай-ақ, розетка ағынын пайдалануға болады (TClientSocket мақаласын қараңыз). Міне, шағын мысал (шамамен):

Розетканы қалай бақылауға болады


Бұл мәселе күрделі және ұзақ қарауды қажет етеді. Әзірге мен сіздің бағдарламаңыз жасаған розетканы әрқашан бақылай алатыныңызды ескертемін :-). Розеткалардың (Windows жүйесіндегі көптеген нысандар сияқты) Handle қасиетінде жазылған өз дескрипторы (тұтқасы) бар. Сонымен, осы дескрипторды үйрене отырып, сіз кез келген розетканы (тіпті басқа біреудің бағдарламасымен жасалған) еркін басқара аласыз! Дегенмен, басқа біреудің ұяшығын бақылау үшін WinAPI Sockets функцияларын пайдалануға тура келеді.


Бұл мақалада Delphi-де TServerSocket компонентімен жұмыс істеудің негізгі амалдары және розеткалар арқылы байланысудың бірнеше жалпы трюктері көрсетілген. Егер сізде сұрақтар болса, оларды маған электрондық пошта арқылы жіберіңіз: [электрондық пошта қорғалған], және одан да жақсысы - осы сайттың форумында жазыңыз (Delphi. Жалпы сұрақтар), басқа пайдаланушылар сіздің сұрағыңызды көріп, оған жауап беруге тырысуы үшін!

Карих Николай ( Nitro). Мәскеу облысы, Жуковский

Бұл мақала Borland Delphi жүйесінде розетка негізіндегі клиент/сервер қосымшаларын жасау туралы. Розеткалар тақырыбына арналған алдыңғы мақаладан айырмашылығы, мұнда біз серверлік қосымшаларды құруды талдаймыз.
Жеке клиенттік және серверлік қосымшалардың қатар өмір сүруі үшін бірнеше компьютердің болуы міндетті емес екенін бірден атап өткен жөн. Серверді де, клиентті де бір уақытта іске қосуға болатын біреуі ғана болса жеткілікті. Бұл жағдайда қосылатын компьютердің атауы ретінде localhost хост атауын немесе IP мекенжайын - 127.0.0.1 пайдалану керек.
Сонымен, теориядан бастайық. Егер сіз табанды тәжірибеші болсаңыз (және көзіңізбен ешқандай алгоритмді көре алмасаңыз), онда бұл бөлімді өткізіп жіберуіңіз керек.
Сокет серверінің алгоритмі
Розетка сервері не істейді?.. Ол қалай жұмыс істейді?.. Розетка протоколына негізделген сервер бір уақытта көптеген клиенттерге қызмет көрсетуге мүмкіндік береді. Сонымен қатар, олардың санына шектеуді өзіңіз белгілей аласыз (немесе әдепкі бойынша бұл шектеуді толығымен алып тастаңыз). Әрбір қосылған клиент үшін сервер жеке ұяшықты ашады, ол арқылы клиентпен деректер алмасуға болады. Сондай-ақ тамаша шешім - әрбір қосылым үшін бөлек процесті (Thread) жасау.
Төменде Delphi қолданбаларында розетка серверінің жұмысының мысалы келтірілген:

Схеманы толығырақ қарастырайық: · Port және ServerType қасиеттерінің анықтамасы – клиенттердің серверге қалыпты қосылуы үшін сервер пайдаланатын порт клиент пайдаланатын портқа дәл сәйкес келуі керек (және керісінше). ). ServerType қасиеті қосылым түрін анықтайды (толығырақ ақпаратты төменде қараңыз); · Ашық розетка – ашық розетка және көрсетілген порт. Мұнда клиенттердің қосылуын күтудің автоматты басталуы (Тыңдау) орындалады; · Клиентті қосу және онымен деректер алмасу – мұнда клиент қосылып, онымен деректер алмасу жүзеге асырылады. Бұл кезең туралы толығырақ осы мақалада және розеткалар туралы мақалада (клиент жағы) кейінірек біле аласыз; · Клиентті ажырату – мұнда клиент ажыратылады және оның серверге розеткалық қосылымы жабылады; · Серверді және ұяшықты жабу - Әкімшінің пәрмені бойынша сервер өшеді, барлық ашық розетка арналарын жауып, клиент қосылымдарын күтуді тоқтатады.
Айта кету керек, 3-4 тармақтар бірнеше рет қайталанады, яғни. бұл элементтер әрбір жаңа клиенттік қосылым үшін орындалады.
Ескерту: Қазіргі уақытта Delphi-де розеткаларға қатысты құжаттама өте аз, сондықтан бұл тақырыпты мүмкіндігінше тереңірек зерттегіңіз келсе, мен сізге Unix/Linux жүйелеріндегі әдебиеттер мен электронды құжаттамаларды - жұмыс теориясын қарауға кеңес беремін. розеткалар онда өте жақсы сипатталған. Сонымен қатар, осы операциялық жүйелер үшін розеткалық қосымшалардың көптеген мысалдары бар (бірақ көбінесе C/C++ және Perl-де).
TServerSocket компонентінің қысқаша сипаттамасы
Мұнда компоненттің негізгі қасиеттерімен, әдістерімен және оқиғаларымен танысамыз.
Қасиеттер
Socket - TServerWinSocket класы, ол арқылы сіз ашық розетка арналарына қол жеткізе аласыз. Әрі қарай, біз бұл қасиетті толығырақ қарастырамыз, өйткені. бұл, шын мәнінде, негізгілерінің бірі. Түрі: TServerWinSocket;
ServerType - сервер түрі. Екі мәннің бірін қабылдай алады: stNonBlocking – клиент ұяшықтарымен синхронды жұмыс. Сервердің осы түрімен OnClientRead және OnClientWrite оқиғалары арқылы клиенттермен жұмыс істеуге болады. stThreadBlocking – асинхронды түрі. Әрбір клиент ұясы арнасы үшін бөлек процесс (Thread) жасалады. Түрі: TServerType;
ThreadCacheSize - сервермен кэштелетін клиенттік процестердің саны (Thread). Мұнда сервердегі жүктемеге байланысты орташа мәнді таңдау керек. Кэштеу әр жолы жеке процесті жасамау және жабық розетканы өлтірмеу үшін, бірақ оларды әрі қарай пайдалану үшін қалдыру үшін орын алады. Түрі: бүтін;
Белсенді – сервердің қазіргі уақытта белсенді немесе белсенді емес екенін көрсететін көрсеткіш. Яғни, шын мәнінде, True мәні сервердің жұмыс істеп тұрғанын және клиенттерді қабылдауға дайын екенін көрсетеді, ал False - сервер өшірілген. Серверді іске қосу үшін бұл сипатты True мәніне орнату керек. Түрі: логикалық
Порт – клиенттермен байланыс орнатуға арналған порт нөмірі. Сервердегі және клиенттердегі порт бірдей болуы керек. 1025-тен 65535-ке дейінгі мәндер ұсынылады, мысалы 1-ден 1024-ке дейін - жүйеде болуы мүмкін. Түрі: бүтін;
Сервис – порты қолданылатын қызметті (ftp, http, pop, т.б.) көрсететін жол. Бұл порт нөмірлерін әртүрлі стандартты протоколдарға сәйкестендіруге арналған анықтамалық кітаптың бір түрі. Түрі: жол
Әдістері
Open - серверді іске қосады. Негізінде, бұл пәрмен Active сипатына True мәнін орнатумен бірдей;
Жабу - серверді тоқтатады. Негізінде, бұл пәрмен Белсенді сипатқа False мәнін орнатумен бірдей.
Оқиғалар
OnClientConnect - клиент розетка қосылымын орнатқанда және сервердің жауабын күткенде пайда болады (OnAccept);
OnClientDisconnect - клиент розетка арнасынан ажыратылған кезде көтеріледі.
OnClientError - ағымдағы операция сәтсіз болғанда көтеріледі, яғни. Қате орын алды;
OnClientRead - клиент берверге кейбір деректерді жіберген кезде іске қосылады. Бұл деректерге берілген Socket параметрі арқылы қол жеткізуге болады: TCustomWinSocket;
OnClientWrite – сервер розеткадағы клиентке деректерді жібере алатын кезде пайда болады;
OnGetSocket - бұл оқиға өңдегішінде ClientSocket параметрін өңдеуге болады;
OnGetThread - осы оқиғаның өңдегішінде SocketThread параметріне қажетті TServerClientThread қосалқы тапсырмасын тағайындау арқылы әрбір жеке клиент арнасы үшін бірегей процесті (Thread) анықтауға болады;
OnThreadStart, OnThreadEnd - сәйкесінше қосалқы тапсырма (процесс, Thread) басталғанда немесе тоқтағанда пайда болады;
OnAccept – сервер клиентке қосылуды қабылдағанда немесе қабылдамағанда іске қосылады;
OnListen - сервер клиенттердің қосылуын күткен кезде көтеріледі.
TServerSocket.Socket(TServerWinSocket)
Сонымен, сервер клиентке деректерді қалай жібере алады? Деректерді қабылдау туралы не деуге болады? Негізінде, OnClientRead және OnClientWrite оқиғалары арқылы жұмыс жасасаңыз, клиентпен ClientSocket (TCustomWinSocket) параметрі арқылы байланысуға болады. Осы сыныппен жұмыс істеу туралы клиент розеткалары туралы мақаладан оқи аласыз. осы класс арқылы деректерді жіберу/жіберу ұқсас - әдістер (Жіберу/Қабылдау) (Мәтін, Буфер, Ағын). Сондай-ақ TServerSocket.Socket бағдарламасымен жұмыс істегенде. Алайда, бері мұнда біз серверді қарастырамыз, кейбір пайдалы қасиеттер мен әдістерді бөлектеу керек: ActiveConnections (Integer) – қосылған клиенттердің саны; ActiveThreads (Integer) – орындалатын процестердің саны; ·Connections (массив) – әрбір қосылған клиент үшін жеке TClientWinSocket кластарынан тұратын массив. Мысалы, келесі пәрмен: ServerSocket1.Socket.Connections.SendText("Сәлем!"); Бірінші қосылған клиентке "Сәлеметсіз бе!" хабарын жібереді. Бұл массивтің элементтерімен жұмыс істеу командалары да (Жіберу/Қабылдау)(Мәтін, Буфер, Ағын); ·IdleThreads (Integer) – бос процестердің саны. Мұндай процестер сервермен кэштелген (TreadCacheSize қараңыз); LocalAddress, LocalHost, LocalPort – сәйкесінше – жергілікті IP мекенжайы, хост атауы, порт; ·RemoteAddress, RemoteHost, RemotePort – сәйкесінше – қашықтағы IP мекенжайы, хост атауы, порт; ·Lock және Unlock әдістері – сәйкесінше розетканың блокталуы және блоктан шығарылуы.
Тәжірибе және мысалдар
Енді жоғарыдағыларды нақты мысалмен қарастырайық. Дайын дереккөздерді осы жерді басу арқылы жүктеп алуға болады.
Сонымен, TServerSocket-пен жұмыс істеудің өте жақсы мысалын қарастырайық (бұл мысал осы компонентті үйренуге арналған ең көрнекі құрал болып табылады). Төмендегі дереккөздер барлық маңызды сервер оқиғаларының журналын, сонымен қатар мәтіндік хабарларды қабылдау және жіберу мүмкіндігін көрсетеді:
Мысал 1. Сервер жұмысын тіркеу және зерттеу, розеткалар арқылы хабарламаларды жіберу/қабылдау.

(... Мұнда файл тақырыбы және TForm1 пішінінің анықтамасы және оның Form1 данасы келеді)

(Толық дереккөзді мына жерден қараңыз)

процедура TForm1.Button1Click (Жіберуші: TObject );

БАСТА

(Біз портты анықтаймыз және серверді бастаймыз)

ServerSocket1.Port := 1025 ;

(Insert әдісі жолды массивке көрсетілген орында кірістіреді)

Memo2.Lines .Insert (0 ,"Сервер іске қосылды" );

ServerSocket1.Open ;

Соңы ;

процедура TForm1.Button2Click (Жіберуші: TObject );

БАСТА

(Серверді тоқтату)

ServerSocket1.Active := False ;

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 ErrorCode: Integer);

БАСТА

(Қате орын алды - оның кодын басып шығарыңыз)

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 ; Socket: Integer ;

var ClientSocket: TServerClientWinSocket);

БАСТА

Memo2.Lines .Insert (0 ,"Get rozetka" );

Соңы ;

процедура TForm1.ServerSocket1GetThread(Жіберуші: TObject ;

ClientSocket: TServerClientWinSocket;

varSocketThread: TServerClientThread);

БАСТА

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

Соңы ;

процедура TForm1.ServerSocket1ThreadEnd (Жіберуші: TObject ;

БАСТА

Memo2.Lines .Insert (0 ,"Жіп соңы" );

Соңы ;

процедура TForm1.ServerSocket1ThreadStart(Жіберуші: TObject ;

Тақырып: TServerClientThread);

БАСТА

Memo2.Lines .Insert (0 ,"Жіпті бастау" );

Соңы ;

процедура TForm1.Button3Click (Жіберуші: TObject );

var i: Integer ;

БАСТА

(Барлық клиенттерге Edit1 хабарламасын жіберіңіз)

i:= 0 үшін ServerSocket1.Socket.ActiveConnections -1 басталады

ServerSocket1.Socket .Connections [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 .Connections [ 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 Кб жіберсеңіз, онда сіз осы блокты жіберген адам трафик пен желі жүктемесіне байланысты өлшемдері бар бірнеше блоктарды алады. Оның үстіне өлшемдердің бірдей болуы міндетті емес. Осыдан файлды немесе кез келген басқа үлкен деректерді алу үшін деректер блоктарын алу керек, содан кейін оларды бір бүтінге біріктіру керек (және, мысалы, файлға сақтау). Бұл мәселенің тамаша шешімі - бірдей файл ағыны - TFileStream (немесе жадтағы ағын - TMemoryStream). ReceiveBuf әмбебап әдісін пайдаланып OnRead (OnClientRead) оқиғасы арқылы розеткадан деректер бөлшектерін алуға болады. Алынған блоктың өлшемін ReceiveLength әдісі арқылы анықтауға болады. Сондай-ақ, розетка ағынын пайдалануға болады (TClientSocket мақаласын қараңыз). Міне, шағын мысал (шамамен):

(Файлды розетка арқылы қабылдау)

процедура TForm1.ClientSocket1Read(Жіберуші: TObject ;

Розетка: TCustomWinSocket);

varl: Integer ;

Buf: PChar ;

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 функцияларын пайдалануға тура келеді.
Эпилог
Бұл мақалада Delphi-де TServerSocket компонентімен жұмыс істеудің негізгі амалдары және розеткалар арқылы байланысудың бірнеше жалпы трюктері көрсетілген. Егер сізде сұрақтар болса, оларды маған электрондық пошта арқылы жіберіңіз: [электрондық пошта қорғалған], және одан да жақсысы - осы сайттың форумында жазыңыз (Delphi. Жалпы сұрақтар), басқа пайдаланушылар сіздің сұрағыңызды көріп, оған жауап беруге тырысуы үшін!
Карих Николай (Нитро). Мәскеу облысы, Жуковский

Мен желілік қолдауды қостым. Бұл бөлек сервер мен бөлек клиентті жасайды. Мәселе мынада, қолданбалы сервер жұмыс істейді, пайдаланушы клиентті іске қосады және пайдаланушыға сұранысты енгізеді: Мәскеу Тверская 6. Содан кейін сервер сұрауды өңдейді, Яндекс.Карталардан іздеу нәтижелерін алады және алынған кескінді клиентке жібереді. , содан кейін пайдаланушы сұранысына сәйкес келетін TMap компоненті берілген картадағы клиентте бөлік көрсетіледі. Нәтижесінде пайдаланушы оны масштабтай алады, сақтай алады және т.б.

Сондықтан, осы мақалада мен клиент пен серверді қалай іске асырғанымды айтқым келеді. Мен мұны TClientSocket және TServerSocket көмегімен жасадым, бұл мақалада біз өз жобамда қолданған әдістерді егжей-тегжейлі қарастырамыз.

Алдымен, осы компоненттерді IDE-ге қалай орнатуға болатынын көрейік. Delphi 7 IDE пайдалансаңыз, әдепкі бойынша бұл компоненттер бар, бірақ, өкінішке орай, олар орнатылмаған, бірақ бұл мәселе емес. Бізге Delphi-ді ашып, орнату керек.

Ол үшін Component-Install Packages… командасын орындап, пайда болған терезеде Қосу түймесін басыңыз. Осыдан кейін әдетте әдепкі бойынша BIN қалтасында орналасқан dclsockets70.bpl файлына жолды көрсету керек. Осыдан кейін сіз OK түймесін басуыңыз керек. Барлығы, сіздің компоненттеріңіз Интернет қойындысында (TClientSocket және TServerSocket) пайда болуы керек.

Жобада мен барлық жұмысты серверді ең аз өңдеумен бастадым. Алдымен пішінге TServerSocket компонентін орнаттым. Және серверді бастау түймесін басу арқылы орнатыңыз бастапқы параметрлер, оны инициализациялау үшін:

сервер. Порт := FormServerSetting. SpinEditPort. құндылық; //сервер портын көрсетіңізсервер. Белсенді := True ; //оны белсендіріңіз Сервер. ашық; ifServer. Белсенді, содан кейін бастаңыз //сервер жұмыс істеп тұрғаны туралы хабарламаны көрсетедіСоңы ; …….. //сервер іске қосылмаған болса, қатені көрсетеді

Менің құрылғымдағы серверді инициализациялау үшін мен тек бос портты (басқа қолданбаларда жоқ) орнатып, оны белсендірдім.

Негізінде, бұл бәрі, жұмыс үшін мен үшін сервердің жұмыс істеп тұрғаны жеткілікті болды және мен олар жіберген клиенттердің сұрауларын өңдей алдым.

Серверге қосылатын клиенттердің тізімін алу және олармен әрі қарай жұмыс істеу үшін мен формаға TCeckListBox компонентін және TServerSocket компонентінің OnclientConnect оқиғасына орнаттым, мен келесі кодты жаздым:

TFormServer процедурасы. ServerClientConnect (Жіберуші: TObject ; Socket: TCustomWinSocket) ; БАСТА //клиент қосылымын бақылау richeditlog. SelAttributes. Түс:=clЖасыл; richeditlog. SelAttributes. Стиль := [fsBold] ; CheckListClient. Элементтер. Add(Socket.RemoteHost); richeditlog. Сызықтар. Қосу ("[" + TimeToStr (Уақыт ) + "] Клиент қосылған: " + Socket. RemoteHost ) ; // қосылған клиентті тізімге қосыңыз richeditlog. Орындау(WM_VSCROLL, SB_BOTTOM, 0) ; Соңы ;

Яғни, олар туралы қосымша ақпарат алу үшін серверге қосылатын клиенттердің атын тізімге қосамын.

Мысалы, алуға болады егжей-тегжейлі ақпаратклиент туралы:

TFormInfoClient процедурасы. FormShow(Жіберуші: TObject) ; БАСТА // клиент туралы ақпаратты басып шығарутақырып:= «Тұтынушы туралы ақпарат:»+ пішін сервер. CheckListClient. Элементтер [FormServer. CheckListClient. ItemIndex] ; жергілікті атау. Жазба := FormServer. Сервер. розетка. Қосылымдар [FormServer. CheckListClient. ItemIndex] . LocalHost; жергілікті хост. Жазба := FormServer. Сервер. розетка. Қосылымдар [FormServer. CheckListClient. ItemIndex] . Жергілікті мекенжай; жергілікті порт. Жазба := IntToStr (FormServer. Сервер. Сокет. Қосылымдар [FormServer. CheckListClient. ItemIndex]. LocalPort); қашықтағы атау. Жазба := FormServer. Сервер. розетка. Қосылымдар [FormServer. CheckListClient. ItemIndex] . қашықтағы хост; қашықтағы хост. Жазба := FormServer. Сервер. розетка. Қосылымдар [FormServer. CheckListClient. ItemIndex] . Қашықтағы мекенжай; қашықтағы порт. Жазба := IntToStr (FormServer. Сервер. Сокет. Қосылымдар [FormServer. CheckListClient. ItemIndex]. RemotePort); Соңы ;

Сіз келесі деректерді ала аласыз:

  • жергілікті атауы
  • Жергілікті мекенжай
  • жергілікті порт
  • қашықтағы атау
  • қашықтағы мекенжай
  • қашықтағы порт

Мен TCheckListBox компонентінің тізімінде таңдаған осы кодты пайдаланып клиент туралы ақпаратты аламын.

Көріп отырғаныңыздай, күрделі ештеңе жоқ, клиентке хабарлама жіберу үшін келесі кодты пайдалануға болады:

IN шаршы жақшалар, хабарды қай клиентке жіберетінімізді көрсетемін (ол TCheckListBox компонентіндегі таңдалған клиентке тең), мен хабарламада #message# көрсетемін - бұл серверден келетін қалыпты хабарлама екенін білдіреді, ол жай ғана болуы керек терезеде көрсетіледі.

Клиенттен серверге хабарлама алу үшін бізге TServerSocket компонентінің OnClientRead оқиғасы және клиент жіберген сұрауды жазатын мәтіндік айнымалы керек.

TFormServer процедурасы. ServerClientRead(Жіберуші: TObject ; Сокет: TCustomWinSocket) ; var query: String ; БАСТА //клиенттен картаға сұраныс алусұрауды қолданып көріңіз:= Socket. ReceiveText ; if pos («сұрау», сұрау)<>0 содан кейін бастаңыз //Яндекстен сұрау немесе Google координаттарыклиенттің сұранысы бойынша карталарСоңы ; //егер клиенттен келген хабарлама болса, оны көрсетіңіз if pos("#хабарлама#", сұрау)<>0 содан кейін басталады аяқталады; ……

Бұл кодтан клиент серверге әдеттегі хабарламаны да, Мәскеу, Тверская, 6 сияқты картаға сұрау жібере алатындығын көруге болады.

Мұны істеу үшін мен кәдімгі хабарламаның қайда екенін және картаны алуға сұраныстың қай жерде екенін анықтауым керек, сонда сервер оны болашақта өңдей алады. Бұл жағдайда, ең басында, мен клиенттің хабарламаларына келесі идентификаторларды қосамын:

  • #хабар#
  • #сұрау#

Егер #хабарлама# идентификаторы клиент хабарламасының басында болса, онда сервер оны клиенттен келген қалыпты хабар ретінде таниды. Хабардың басында #сұрау# идентификаторы болса, бұл клиент картаны алуға сұраныс жібергенін білдіреді.

Сондай-ақ, клиент серверден кез келген уақытта ажырата алады, біз оны серверге қосылған клиенттердің жалпы тізімінен жою үшін оны бақылауымыз керек. Ол үшін TServerSocket компонентін таңдап, OnClientDisconnect оқиғасына келесі кодты жазыңыз:

TFormServer процедурасы. ServerClientDisconnect (Жіберуші: TObject ; Socket: TCustomWinSocket) ; var i: integer ; көріңіз бастаңыз //клиенттің өшірілуін бақылау richeditlog. SelAttributes. Түс:=clRed; richeditlog. SelAttributes. Стиль := [fsBold] ; i үшін := 0 серверге. розетка. ActiveConnections - егер сервер болса, 1 басталады. розетка. Қосылымдар[i]. Тұтқа = сервер. розетка. Қосылымдар[i]. Өңдеу, содан кейін RichEditLog бастаңыз. Сызықтар. Қосу ("[" + TimeToStr (Уақыт ) + "] Клиент ажыратылды: " + Socket. RemoteHost ); CheckListClient. Элементтер. Жою(i) ; richeditlog. Орындау(WM_VSCROLL, SB_BOTTOM, 0) ; Соңы ; Соңы ; ақырында //-//-//-///-//-// соңы; Соңы ;

Біз тізімде бар барлық клиенттерді аралап шығамыз, егер оларды таппасақ, оны TCheckListBox компонентінен алып тастаймыз, яғни клиент өз қолданбасындағы «Ажырату» түймесін басқан.




Жоғарғы