KVIrcОсновы KVS: Работаем с сокетом.

Сегодня мы попытаемся немного поработать с сокетами в KVS. Для этого напишем свой простенький telnet-клиент.

Для работы с сокетами есть специальный класс socket.
Рассмотрим некоторые его функции которые нам понадобятся.

$status() — возвращает статус нашего соединения 0 — отсоединён, 1 — вызов DNS, 2 — соединяемся, 3 — слушаем порт, 4 — соединены.
$connect(host,port) — устанавливаем соединение с хостом host порт port.
$read(length) — возвращает прочитанные данные из сокета с длиной length, если длину не установить то читается до конца.
$write(data) — пишем данные в сокет.
$dataAvailableEvent(data_length) — событие выполняемое при получении данных.
$close() — закрываем сокет.
$connectFailedEvent(reason) — событие выполняемое при ошибке соединения.
$connectEvent() — событие которое выполняется при соединении.
$disconnectEvent() — событие которое выполняется при разединении.

Скрипт у нас будет выглядеть как окно 640х480 с полями для ввода хоста, порта, кнопки соединения и полем ввода команд внизу.
Описание как всегда я буду давать как комменты в тексте скрипта.

alias(telnet)
// создаём новый класс telnet как потомок класса socket
	class(telnet,socket)
	{
		constructor()
		{
// Собираем интерфейс.
// Создаём виджет с заголовком "Telnet" и геометрией 640х480 пикселей.
			@%tWin = $new(widget,$$)
			@%tWin->$setCaption("Telnet")
			@%tWin->$setGeometry(0,0,640,480)

// Используем класс label для указания названий полей.
			@%tWin->%lHost = $new(label,@%tWin)
			@%tWin->%lHost->$setGeometry(5,5,35,20)
			@%tWin->%lHost->$setText("Host:")
			@%tWin->%lPort = $new(label,@%tWin)
			@%tWin->%lPort->$setGeometry(250,5,30,20)
			@%tWin->%lPort->$setText("Port:")

// Используем класс lineedit для формирования полей ввода
			@%tWin->%leHost = $new(lineedit,@%tWin)
			@%tWin->%leHost->$setGeometry(45,5,200,20)
			@%tWin->%lePort = $new(lineedit,@%tWin)
			@%tWin->%lePort->$setGeometry(285,5,200,20)

// Создаём кнопку соединения при помощи класса toolbutton.
			@%tWin->%btConnect = $new(toolbutton,@%tWin)
			@%tWin->%btConnect->$setGeometry(555,5,80,20)
			@%tWin->%btConnect->$setUsesTextLabel(1)
			@%tWin->%btConnect->$setTextLabel("Connect")

// Создаём многострочный редактор для отображения данных полученных из сокета
// и делаем его readonly
			@%tWin->%meOut = $new(multilineedit,@%tWin)
			@%tWin->%meOut->$setGeometry(5,30,630,420)
			@%tWin->%meOut->$setReadOnly(1)

// Создаём ещё одно поле ввода для команд.
			@%tWin->%leIn = $new(lineedit,@%tWin)
			@%tWin->%leIn->$setGeometry(5,455,630,20)

// Привязываем обработку нажатия кнопки Enter в поле ввода команд к функции отправки команды
			objects.connect @%tWin->%leIn "returnPressed" $$ sendData

// Привязываем нажатие кнопки соединения к функции соединения.
			objects.connect @%tWin->%btConnect "clicked" $$ tconnect

// Отображаем наш виджет.
			@%tWin->$show()
		}
		destructor()
		{
			if(@$status() == "4")
			{
				@$close();
			}
		}
		connectEvent()
		{
// Отображаем с чем мы соединяемся.
			@%tWin->%meOut->$append("[$date(H:M:S)] Connected to $$->$remoteIp():$$->$remotePort()")
		}

		disconnectEvent()
		{
// Сообщение при отключении.
			@%tWin->%meOut->$append("[$date(H:M:S)] Disconnected ($0-)")
		}

		connectFailedEvent()
		{
// Сообщение при ошибке соединения с указанием ошибки
			@%tWin->%meOut->$append("[$date(H:M:S)] Connect failed ($0-)")
		}

// Обрабатываем наши данные при получении их из сокета и отображаем.
		dataAvailableEvent()
		{
			%data = $$->$read()
			@%tWin->%meOut->$append("[$date(H:M:S)] $str.replace(%data,"",$char(13))")
		}

// Функция отправки данных.
		sendData()
		{
			if(@%tWin->%leIn->$text())
			{
				@$write(@%tWin->%leIn->$text()\r\n)
				@%tWin->%meOut->$append("[$date(H:M:S)] @%tWin->%leIn->$text()")
				@%tWin->%leIn->$setText("")
			}
		}

// Наша собственная функция соединения с проверкой наличия имени или ip хоста и состояния соединения.
// Если есть соединение то просто отключаемся.
		tconnect()
		{
			@%host = @%tWin->%leHost->$text()
			@%port = @%tWin->%lePort->$text()
			if(@$status == "0")
			{
				if(@%host != "")
				{
					if(@%port == "")
					{
						@%port = "21"
						@$connect(@%host,@%port)
						@%tWin->%btConnect->$setTextLabel("Disconnect")
						@%tWin->%meOut->$append("[$date(H:M:S)] Соединяемся с @%host порт @%port")
					}
					else
					{
						@$connect(@%host,@%port)
						@%tWin->%btConnect->$setTextLabel("Disconnect")
						@%tWin->%meOut->$append("[$date(H:M:S)] Соединяемся с @%host порт @%port")
					}
				}
				else
				{
					@%tWin->%meOut->$append("[$date(H:M:S)] Не указан хост!!!")
				}
			}
			if(@$status() == 4)
			{
				@%tWin->%btConnect->$setTextLabel("Connect")
				@$close()
			}
		}
	}

// Запуск класса.
	%telnet = $new(telnet)
}


Вот такой вот простенький пример для работы с сокетами.

Комментарии (2)

Поставьте кат.
Извините. в конце рабочего дня дописывал. По работе отвлекли, а потом и забыл про тэг. Опубликовал и домой рванул.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.