Tcl

Tk

Tcl/Tk

Статьи

Многопоточный сервер

Единая страна

Многопоточный сервер

Многопоточный сервер - doro.poltava.ua

Многопоточный сервер

При проектировании сервера, важно предусмотреть возможность одновременной обработки запросов от нескольких клиентов. Одним из способов реализации такого подхода - использование многопоточности. В Tcl это реализуется с помощью библиотеки thread. В этой статье, мы рассмотрим пример сервера, обслуживающего клиентов с постоянным удержанием сетевого соединения.


# загружаем библиотеку потоков
package require Thread
# запускаем слушатель на 7000 tcp порту
# при получении запроса от клиента, будет запускаться процедура _Accept
socket -server _Accept 7000
# входим в обработчик tcl событий
# это важная строка, без неё tcl-приложение завершится. 
# Для Tk-приложения данная строка не нужна.
vwait forever

# запуск процедуры создания потоков
proc _Accept {idsocket ipaddr port} {
  # порождаем поток только в свободные циклы работы интерпретатора
  after idle [list Accept $idsocket $ipaddr $port]
}

# Собственно, функция порождения потока
proc Accept { idsocket addr port } {
  # переменная с указанием ваших действия перед порождением потока
  set threadinit {
    # если необходимо, загружаем сторонние библиотеки
    foreach { p } { mkZiplib base64 Pgtcl md5 tls } {
      package require $p
    }

    # если необходимо, загружаем исходный tcl код, расположенный в других файлах
    foreach { s } { lib log protocol error mainthread } {
      uplevel #0 source $s.tcl
    }
    
    # не завершаем поток, ибо будет запущен событийный сокетный обработчик
    thread::wait
  }

  # порождаем поток, выполнив предварительные действия, описанные в переменной threadinit
  set tid [thread::create $threadinit]
  # передаем сокет с главного интерпретатора в интерпретатор порождённого потока
  thread::transfer $tid $idsocket
  # запускаем поток в асинхронном режиме
  thread::send -async $tid [list Accept:Thread $tid $addr $idsocket]
}

# процедура создания событийного чтения данных из сокета
proc Accept:Thread { tid addr idsocket } {
  # конфигурируем сокет
  # важно, для событийной обработки чтения данных с сокета, сокет должен быть в неблокирующем режиме
  fconfigure $idsocket -blocking 0 -buffering full -encoding binary -translation binary
  # создаём событийный обработчик чтения данных с потока
  # при возникновении данных на сокете, запускается процедура SocketEventHandler:Thread
  fileevent $idsocket readable [list SocketEventHandler:Thread $idsocket]
}

# читаем данные с сокета
proc SocketEventHandler:Thread { idsocket } {
  if { [eof $idsocket] || [catch {gets $idsocket pkt}] } {
    # уничтожаем поток
    Exit:Thread $idsocket
  } else {
    # здесь помещаем код по обработке полученного пакета
    # переменная pkt содержит полученные данные от клиента
  }
}

# процедура завершения потока
proc Exit:Thread { idsocket } {
  # закрываем сокет
  close $idsocket
  # уничтожаем, останавливаем поток
  thread::release
}

Такой тип организации сервера, лучше использовать для клиентов, которые постоянно удерживают сокетное соединение. В данном случае, для каждого клиента создается новый поток. Этот подход приемлем при небольшом количестве подсоединяемых клиентов (50-100). Для обработки большего количества клиентов, сервер необходимо строить по технологии пула потоков. Это мы рассмотрим в следующей статье.



Главная
Программные продукты
Freesource программные продукты
Статьи
Контакт
GPSMTA - GPS трекер / GPS мониторинг для Android
GPSM - программно-аппаратный комплекс GPS мониторинга
MapTour - GPS навигация для Туристов
MapSurfing - просмотрщик географических карт
DGraf - визуализация графов
ViCer - домашняя система видеонаблюдения
FPS - бесплатная система GPS мониторинга
Jeans - Финансово-складской учёт
Cerber - Финансовый учёт игорного зала
Visimap - Визуальная карта
BIB - Картотека книг
2DO - Учёт рабочего времени
Выписка - склад
Расчёт зарплаты
Krp - визуализатор связанных структур
Xboat - проэктировщик малых судов
XSQLite - visualisator DB SQLite
Текстовый редактор XEdJ
Copyright © Эдуард Зозуля
Проверка PR и ТИЦ