Сокетите в неблокиращ режим
Сайт на Delphi: ежедневни Delphi-новини, документация, статии, преглед, интервю, компютърен хумор.
Когато работите в режим на блокиране, за да не виси програмата, трябва да използвате много нишки. Това е неудобно и се губи ценно процесорно време.
Използвам режим на блокиране само когато програмирам услуги на Windows NT или други програми, които нямат потребителски интерфейс и са невидими. В този случай потребителят няма да забележи ключалката и можете да опростите живота си. В други случаи използвам само неблокиращ режим, който е малко по-труден за програмиране, но удобен от гледна точка на изпълнение.
Неблокиращите (асинхронни) сокети са по-трудни за програмиране, но нямат недостатъците на блокиращите. В асинхронен режим програмата, след като извика мрежовата функция, продължава да работи, без да чака резултата от изпълнението. По този начин няма да можем да разберем как всъщност е работила функцията, но производителността се увеличава поради факта, че не са необходими допълнителни нишки. Вместо да "замразява" програмата извършва полезни действия, постига се паралелно изпълнение на задачите.
За да настроите сокет в неблокиращ режим, трябва да използвате функцията socket ioctl, която е описана по следния начин:
Помислете за параметрите на функцията на ioctl socket:
• arg - параметър за командата.
Режимът на блокиране се променя чрез посочване на константата FI0NBI0 като втори параметър (команда). В този случай, ако третият параметър показва нулева стойност, тогава ще се използва режимът на блокиране, в противен случай - неблокиращ.
Нека да разгледаме пример за създаване на сокет и настройката му на неблокиращ режим:
край, Сега всички функции за получаване / предаване и свързване къмсървърът ще се провали. Това е нормален отговор и трябва да се вземе предвид при изграждането на неблокиращи мрежови приложения. Ако I/O функция върна грешка WSAEW0ULDBL0CK, това не е индикация, че функцията не работи правилно. Всичко мина добре, просто използвах неблокиращ режим. Ако възникне грешка, тогава ще получим грешка, различна от WSAEW0ULDBL0CK.