Для работы с этими протоколами в среде Windows предназначена технология Windows Sockets.
Реализует эту технологию библиотека Mswinsock.dll (Mswinsock.ocx).
В качестве транслятора в протоколы TCPIP или UDP данных из (в) 1С:Предприятие можно использовать ActiveX компоненту, входящую в состав библиотеки Mswinsock.dll.
Эта библиотека входит в состав пакета Visual Basic который можно установить вместе с пакетом программ MS Office. Ну или найти в Интернете.
Её полноценное использование в среде 1С:Предприятие возможно только в качестве ActiveX элемента на форме.
На форме появится значок с двумя компьютерами, примерно такой (все зависит от используемой вами операционной системы и версии библиотеки).
Не забудьте для компоненты снять флажок видимости. Компонент не имеет элементов интерфейса, тем не менее 1С пытается его отрисовать, что приводит к некрасивым результатам.
После добавления компонента на форму становятся доступными все связанные с ним свойства и события. Наиболее часто используемые события добавляются на форму свойств.
Остальные свойства и события доступны через контекстную подсказку «IntelliSense» в модуле формы.
Свойства.
Из дополнительных свойств стоит отдельно выделить свойство «State» в это свойство содержит числовое значение текущего состояния компоненты — Статус.
Список возможных значений
Состояние | Числовое значение | Описание |
sckClosed | 0 | Default. Closed Значение по умолчанию. Подключение закрыто. |
sckOpen | 1 | Open Подключение активно. Соединение установлено. |
sckListening | 2 | Listening Режим «прослушки». Компонента ждет подключение по указанному порту. |
sckConnectionPending | 3 | Connection pending Ожидание подключения |
sckResolvingHost | 4 | Resolving host Получение адреса компьютера (хоста) по имени. |
sckHostResolved | 5 | Host resolved Адрес компьютера получен. |
sckConnecting | 6 | Connecting Подключение |
sckConnected | 7 | Connected Подключен |
sckClosing | 8 | Peer is closing the connection Клиент закрыл подключение |
sckError | 9 | Error Ошибка |
Свойство Protocol содержит числовой параметр, указывающий, с каким протоколом работать. Protocol принимает одно из двух возможных значений
- 0 — протокол TCP/IP
- 1 — Протокол UDP
Свойство LocalPort числовой параметр, указывающий, какой порт будем прослушивать функцией Listen().
Свойства RemotePort и RemoteHost — это параметры, указывающие по какому адресу (IP или DNS) и на какой порт совершать подключение к серверу функцией Connect().
Для каждого параметра есть одноименная функция, которая возвращает текущее значение параметра или устанавливает новое значение. За исключением параметра State, для разработчика этот параметр ReadOnly.
Доступные события.
Error — Событие возникает при возникновении какой-либо ошибки.
Сообщить(Description);
КонецПроцедуры
В параметрах события возвращается
- Number — цифровой код возникшей ошибки,
- Description — текстовое описание ошибки,
- Scode — код ошибки в типе Long (HRESULT) SCODE
- Source — описание источника ошибки,
- HelpFile — ссылка на Файл справки
- HelpContext — контекст файла справки
- CancelDisplay — флаг отмены отображения стандартного окна об ошибке. По умолчанию значение — Истина. Окно не выводится.
DataArrival — возникает при поступлении данных.
ТкстСообщения = «»;
WinSocket1.GetData(ТкстСообщения);
Сообщить(«Получен ответ» + Символы.ПС + ТкстСообщения);
КонецПроцедуры
В параметр bytesTotal передается числовое значение, сколько байт было принято. Сами данные можно получить функцией GetData(). В параметр этой функции нужно передать строковую переменную, в которую функция вернет полученные данные.
Connect — событие возникает при успешном подключении к серверу. Возникает только на стороне клиента.
КонецПроцедуры
Это событие не имеет собственных параметров.можно работать только с параметрами самой компоненты.
ConnectionRequest — серверное событие, возникает при поступлении запроса на подключение.
Если НЕ
WinSocket.State = 0 ТогдаWinSocket.Close()
КонецЕсли; WinSocket.Accept(requestID); Сообщить(«Приконнектился «+WinSocket.RemoteHostIP);
КонецПроцедуры
В параметр requestID поступает идентификатор подключаемого клиента. При этом, обратите внимание, что перед разрешением на подключение функцией Accept(requestID) необходимо компоненту перевести в состояние «0», т.е. закрыть открытый прослушиваемый поток.
Тут же можем получить IP-адрес подключаемого клиента из параметра RemoteHostIP.
Теперь, после установления соединения, можем передавать данные в обе стороны.
Close — Событие, возникающее при вызове метода Close() т.е. при закрытии компоненты.
SendProgress — Событие, возникающее при передаче данных, возникает при каждом переданном байте — так что не стоит навешивать слижком громоздкую или ресурсоемкую логику. Да и как показала практика, в 1С это событие использовать нет смысла, потому как процедура, связанная с этим событием, срабатывает только 1 раз, когда форма получает обратно фокус ввода.
Следующая процедура выводит прогресс отправки в окно служебных сообщений. По сути должна выводить сообщение для каждого отправленного байта. Но следующая картанка показывает что это не так.
КонецПроцедуры
Из картинки видно, что вызов процедуры произошел только один раз.
SendComplete — Событие, возникающее при завершении отправки данных. Следующий код демонстрирует функционирование данного события.
Сообщить(«» + + ТекущаяДата() + » |Отправка данных завершена! «);
Сообщить(«————————————«);
КонецПроцедуры
Ну и сам результат вызова.
Оригинал статьи на nastroy-ka.ru
При интеграции 1С:Предприятие с другими системами возможны случаи когда работа возможна только по протоколам TCPIP или UDP. Платформа 1С не предоставляет механизмов для прямого взаимодействия с этими протоколами, что крайне неудобно, но, тем не менее, не невозможно.
Для работы с этими протоколами в среде Windows предназначена технология Windows Sockets.
Реализует эту технологию библиотека Mswinsock.dll (Mswinsock.ocx).
В качестве транслятора в протоколы TCPIP или UDP данных из (в) 1С:Предприятие можно использовать ActiveX компоненту, входящую в состав библиотеки Mswinsock.dll.
Перейти к публикации
Полезно. Сама идея не нова — было в книге «1С. Системное программирование». Но там всё в коде создавалось и менее подробно описано. Однозначно «+», сам через ВК с сокетами работал, если бы раньше наткнулся…
А раньше статьи и не было. я сам решил написать стать только когда сам с этим столкнулся.
В этом способе есть одна сушественная проблема. еслисоздавать сервер на стороне 1С то сервер принимает только одно подключение. Создать стек серверов из одной компоненты, как это делается в примерах для C# или VB. тут не получится, а жаль.
Автор, молодец, что довел до народа данный принцип. Правда сервер на до писать на чем то продвинутом например на делфи, или компоненту писать с сервером.
(3) zavedeev, Я с вами согласен, но не полностью. Если сервер поддерживать так же мне, а я кроме 1С больше ни одного языка программирования толком не знаю и реализация сервера займет очень длительный период, не говоря уже о не опртимальном коде. То мне проще реализовать все на платформе 1С. Тем более, что производительность платформы по сравнению с ВК не так уж и отличается. ВК несомненно быстрее и стабильнее, хотя, как мне кажется это превосходство в рамках прогрешности инструмента замера производительности, да и стабильность зависит ом уровня программиста, реализовавшего ВК.
Я считаю, что при таких мизерных различиях реализация сокетов на платформе 1С имеет больше преимуществ чем ВК. Взять хотя бы открытость кода.
P.S. В ближайшее время на суд обществености предоставлю конфу которая как раз и реализует своеобразный мультиканальный Socket’s-проксисервер.
Padonak-XXI, с большим удовольствием буду ждать конфу!
Познавательно
Спасибо, статья интересная
Статья интересная, но таки серверную часть на 1С наверное не стоит делать.
Отправить данные(клиент)- да, но сервер ожидающий прихода данных из вне(например в бесконечном цикле)…. это на 1С реализовать мне кажется нормально не получится.))
Поэтому я писал свою ВК на C#, примеров в инте много, даже не зная языка мне это удалось за пару дней))
(8) sanfoto, Никаких бесконечных циклов тут и не требуется. Достаточно перевести компоненту в состояние Listen. И она будет ждать подключений до скончания века, ну или пока конфу не закроют 🙂
И такой закономерный вопрос: Зачем писать ВК для работы с другой ВК?
Давно использую этот АктивИкс, только он входит не в состав библиотеки Mswinsock.dll. Он входит в состав MS Visual Studio 6 как компонент Visual Basic — Mswinsck.ocx
(10) oleg_km,
Может быть, спорить не буду.
Не нужно спорить, просто уточнил, где его можно взять, он же с операционкой не устанавливается
(12) oleg_km, он по моему устанавливается вместе с офисом. Потому как у меня на работе более никакого Visual Basic нет.
Исправлю в статье информацию о том где взять компоненту.
Ну тогда нужно с этим разобраться и дать в статье информацию, где его брать. Мы этот компонент сами ставим на каждый новый компьютер при его начальной настройке
Полезно и подробно.
(11) не может быть, а так точно. является частью проприетарного ПО, поэтому на обычном компе без васика, ее(библиотеки) нет. Для её регистрации требуется внести лицензионный ключ в реестр. Сама библиотека — обычный com сервер, поэтому вовсе необязательно для этого использовать форму/activex.
(16) cool.vlad4, Использование именно в режиме ActiveX позволяет работать с событиями самой компоненты, а не отслеживать состояния через бесконечные циклы (пример использования цикла с проверкой параметра State можно найти в книге 1С:Предприятие 7.7/8.0 Системное программирование. Стр. 20). Причиной невозможности работать с событиями в режиме Com-автоматизации является то, что все методы у библиотеки асинхронные. Соответственно, поймать изменение состояния можем либо через цикл, постоянно считывая параметр State, либо перехватывая соответствующее событие на форме.
Еще одним преимуществом использования событий по сравнению с Com-сервером, вижу то, что 1С не «зависает» отслеживая циклами изменение состояния.
(17) я прекрасно работал с winsock как с com сервером и с событиями. Добавляются события через стандартную ф-цию ДобавитьОбработчикСобытия.
Функция СоздатьОбъект() Экспорт
Попытка
ws = Новый COMОбъект(«mswinsock.winsock»);
Исключение
Возврат Ложь;
КонецПопытки;
//Попытка
ДобавитьОбработчик ws.Close, Close;
ДобавитьОбработчик ws.Connect, Connect;
ДобавитьОбработчик ws.ConnectionRequest, ConnectionRequest;
ДобавитьОбработчик ws.DataArrival, DataArrival;
ДобавитьОбработчик ws.Error, Error;
ДобавитьОбработчик ws.SendComplete, SendComplete;
ДобавитьОбработчик ws.SendProgress, SendProgress;
//Исключение
//КонецПопытки;
Возврат Истина;
Со State там я помню была другая трабла, но я видел как-то тему на мисте, где описывалось решение. сейчас не помню, поскольку этим винсоком уже не пользуюсь. ну его нафиг.
(19) cool.vlad4, Опачки… Век живи — век учись. я и не знал о возможности привязки обработчиков.
Спасибо за пример.
Как же мне не хватало этой статьи год назад… Вы просто представить не можете — сколько времени я мог бы сэкономить… Теперь это попробую уже не для проекта, а для собственных «глупостей» навроде управлением из 1С всякими ничтяками ) Огромное спасибо автору!
(22) Bezeus, Да пожалуйста.
Спасибо! Интересная информация
Скачал данную обработку. Не работает. Ругаеться на поле объекта.
Библиотека зарегистрирована в элементах ActiveX отображаеться нормально.
Что нибудь надо дописывать?
{Форма.Форма.Форма(5)}: Поле объекта не обнаружено (State)
Если WinSocket.State <> 0 тогда
(25)Вообще-то ничего дописывать не надо. Обработки рабочие. Проверялось на Win XP в режиме домена, Win 7 HP, Win Server 2008 и Win Server 2008 R2.
Попробуйте в режиме отладки проверить, что находится в объекте WinSocket, скорее всего у вас не создается COM-объект.
кто нибудь перепишет на управ. приложение
(34) Да не за что извиняться, бывает оппоненты и на эмоциях ведут дискуссию.
Относительно вашего замечания по использованию технологий .Net — полностью с вами согласен! Но я не спец по этой технологии и написать соответствующую ВК не в состоянии, нужно потратить много времени на изучение, а нужно было здесь и сейчас, вот и пришлось использовать то, что есть.
Помогите плиз, дайте саму компоненту, не могу найти то, что нужно под win 2008 server 64.
(36)Под win 2008 server 64 компоненты не существует, нужно использовать старую (под X86) найти саму компоненту с инсталятором не сложно.
Как старую компоненту заставить работать на X64 показано на видео
(37) DMSDeveloper, спасибо большое. А можешь мне ссылочку на работающую компоненту дать ? Я нашел каких то две с одинаковым названием и абсолютно разынм размером: 10 мб и 100 кб. И еще вопросик .. Как их регистрировать ? regsvr32 ругнулся на них. Достаточно их просто пометсить в System32 или что то еще нужно делать кроме того, что на видео ? Спасибо !
(38) Я использую вот эту сборку
winsock_x64.rar
(39) DMSDeveloper, спасибо огромное, буду пробовать. С поддержкой многопоточности всё ок ? У меня будет до 200-х устройств, которые будут слать пакеты раз в 30 сек. Можно, конечно, разбить по портам 1с-ки (например по 40 устройств на один порт) и запустить 5 1с-ок. Как думаешь? Есть такой опыт ?
да, спасибо, интересная статья
будут подобные посты еще ?
(40) В выложенном примере многопоточности нет. В «классическом» приложении многопоточность организуется формированием массива из инициализированных mswinsck, для этого при инициализции устанавливается параметр компоненты index. 1С, к сожалению, этот параметр не видит и работать с ним отказывается.
Вот пример MswinSock-Proxy
Я эту проблему решил следующим образом
1. создаю обработку «прослушку» предопределенного порта
2. когда на порт поступает входящий запрос создаю инстанс обработки «proxy» в которой назначаю новый порт и передаю этот порт клиенту с требованием переподключиться на него.
3. «Прослушку» опять перевожу в режим прослушки на предопределенный порт.
В примере нет справки и код не причесан, но суть понять можно.
(41)
Не за что.
(42)
Пока ничего такого специфического на работе не попалось, так что пока не будет.
Спасибо за полезную статью.
(43)
По многопоточности. Теоретически можно подойти к вопросу еще одним образом. Программно разместить на форме требуемое количество невидимых экземпляров ActiveX WinSock в соответствии с количеством портов, требующих прослушки. Программно назначить им одни и те же процедуры-обработчики событий. При этом в каждую процедуру при наступлении события будет платформой передаваться соответствующий экземпляр компоненты в параметр «Элемент», т.о. мы сможем всегда определить от какого экземпляра пришло событие и обработать его соответствующим образом.
Как Вам такая идея реализации?
(45) Lantastic, Для использования разных портов такой вариант возможен. Но, если вам нужен пул коннектов на одном порту, такой вариант не проканает. Платформа 1С не поддерживает индексы.
подробнее про индексы в (43).
А если посмотреть на пример из (19) то необходимость создавать компоненты на форме отпадает сама собой. И приведенные примеры можно организовывать на стороне сервера.
Использование компоненты на стороне сервера сразу решает вопрос использования компоненты в управляемых формах.
Это решение вопроса для (27)
(46) Да, вполне согласен, мой вариант для параллельной прослушки набора портов, а не получения пула на один порт от разных.
Но если нужно прослушивать много портов, подход в (19) усложняет жизнь. Если мы назначим программно события, мы в событии не узнаем каким конкретно экземпляром оно рождено. Либо создавать наборы событий для каждого экземпляра, но это не всегда гибко.
Для параллельной прослушки набора портов ваш способ наилучшее решение.
А из (19) можно взять реализацию программного создания экземпляра библиотеки с привязкой процедур в модуле объекта, а не на форме — позволит работать на стороне сервера в фоне.
Пример
Попытка
ws = Новый COMОбъект(«mswinsock.winsock»);
ДобавитьОбработчик ws.Close, Close;
ДобавитьОбработчик ws.Connect, Connect;
…
КонецПопытки;
Попытка
ws_2 = Новый COMОбъект(«mswinsock.winsock»);
ДобавитьОбработчик ws_2.Close, Close_2;
ДобавитьОбработчик ws_2.Connect, Connect_2;
…
КонецПопытки;
Коллеги!
Есть проблема в Winsock.
На Windows server 2008 32-bit компонента не работает нормально.
При размещении ActiveX объекта на форме добавляется новый элемент, но в палитре свойств нет его специфических свойств и событий. Программно тоже не видит свойства и методы.
На Windows XP работает нормально.
На Windows 7 такая же проблема.
Может, кто сталкивался с проблемой?
(49)Разобрались. Оказывается одного mswinsck.ocx файла с компонентой не достаточно. Пока точно не выяснили, что именно еще требуется, чтобы ActiveX виделся в 1С правильно. Но помогла установка пакета ActiveX из дистрибутива Visual Basic 6.
(50) Странно, мне хватило только двух файлов и записи ключа в реестр.
1.MSWINSCK.ocx
2.license.reg
3.mswsock.dll — это стандартная библиотека Windows
Ключик из license.reg
[HKEY_CLASSES_ROOTLicenses2c49f800-c2dd-11cf-9ad6-0080c7e7b78d]
@=»mlrljgrlhltlngjlthrligklpkrhllglqlrk»
(0) а не сталкивались с ситуацией когда надо принимать двоичные данные? По идее GetData корректно получает двоичные данные от сервера, но вот как корректно их принять в 8ке?
Здравствуйте. А можно каким-то образом на WinSock послать не строковое значение, а байт кодировки HEX (шестнадцатиричный) ?. Т.е. нужно послать что-то типа 0x1F.
Добрый день!
А подскажите пож-а, в фоновом задании программно создаю WinSock, подключаюсь как положено через Connect(), назначаю для него событие «ДобавитьОбработчик ws.Connect, Connect» кручу бесконечный цикл, а в событие не падает? Почему? Возможно ли вообще реализовать вызов внешних событий в фоновом задании?
При использовании того же когда на клиенте, все работает ок.
Показать
Пишет, что «Метод объекта не обнаружен»…ни один…в чем может быть проблема ?
С созданным на форме объектом работало нормально, но нужно создавать программно, а я не могу назначить ему обработчики событий.
Показать
Пишет, что «Метод объекта не обнаружен»…ни один…в чем может быть проблема ?
С созданным на форме объектом работало нормально, но нужно создавать программно, а я не могу назначить ему обработчики событий.
(49) Lantastic, у меня такая же проблема, установил пакет MS VB6 вместе с ActiveX, но не помогло, т.е. событий в палитре нет =(
У меня на 1с77 не работает
Подскажите, пожалуйста, что можно сделать?
(53) tro2001,
http://infostart.ru/public/319296/
Возможно это вам поможет:
(54) php5,
Вы проверяли: комобъект winsock у вас создается в фоновом задании?
У кого-то есть опыт работы с WinSocket на управляемых формах в тонком клиенте? Поделитесь.
При использовании кода через пару секунд (наверное на подключение) 1с просто ругает на Runtime и валится((
Показать
Прошу прощения спутал с Web Soсkets
Есть примеры работы по TCP/IP
(43) DMSDeveloper, Спасибо за cf’ник. Помог победить печать на Штрих-600 с помощью ESC последовательностей и компоненты Windows Sockets из управляемого приложения.
Я считаю, что при таких мизерных различиях реализация сокетов на платформе 1С имеет больше преимуществ чем ВК. Взять хотя бы открытость кода.
P.S. В ближайшее время на суд обществености предоставлю конфу которая как раз и реализует своеобразный мультиканальный Socket’s-проксисервер.
(4) написали конфу уже?
Питаюсь отправить данные на tcp сервер с тонкого клиента.
Процедура на клиенте
Показать
Статус постоянно 6. В какие-то моменты сервер принимает подключения, но самого сообщения нет.
Подскажите как решить проблему? спасибо!
(65) Разобрался. Нужно разделить подключение и отправку на 2 процедуры. + после отправки нужно закрывать соединение, так как посылка не уходит. Не уходить причем и на толстом и на тонком клиенте
(64) Gendalf_beliy,
Нет, отпала в ней необходимость.
(66) ROM_1C, Разделил подключение и отправку на две процедуры. Процедуру получения выполняю НаСервере. Ничего не получаю. Хотя подключение происходит.
Подскажите, как у вас реализовано?
На форме поле есть?
Как с помощью этой компоненты вытянуть IP адрес подключаемого к терминалке клиента?
(71)
Никита, с этой компонентой никак, посмотри в командах WMI для работы с окружением ОС.
Там скорее всего есть.
(70)
при вызове на сервере валится с ошибкой
Ошибка при вызове конструктора (COMОбъект)
WinSocket = Новый COMОбъект(«MSWinsock.Winsock»);
по причине:
-2147221164(0x80040154): Class not registered.
Платформа 8.3.12.1567.
На клиенте всё работает…
Sub Winsock_Connect
MsgBox «IP address for » & Server & » is » & _
Winsock.RemoteHostIP, vbInformation, AppName
CloseMsgBox
End Sub
Узнать IP-адрес удаленного компьютера можно так как метод Connect является асинхронным — то есть возврат из него осуществляется сразу же, не дожидаясь установления соединения. Чтобы узнать о соединении (или о произошедшей ошибке), нам нужно дождаться события Connect (или, соответственно, события Error). Воспользуемся простейшим вариантом — после метода Connect покажем message box, а после получения события — закроем его.