Страница 2 из 8 ПерваяПервая 1234 ... ПоследняяПоследняя
Показано с 11 по 20 из 75

Тема: SysSockCreate

  1. #11

    По умолчанию

    bResult:=SysSockListen(diSocket, diMaxConnections);
    IF bResult < 0 THEN
    diSocket:=SOCKET_INVALID;
    END_IF

    Это помогло, Спасибо
    Но все ровно я не понял в чем разница.

    По поводу дотошности, дело в том что задача стоит массовая и чем меньше всяких
    косяков тем будет проще все это дело обслуживать.

    “ни при каких обстоятельствах нельзя останавливать плк не закрыв открытые сокеты”
    Что это значит?

  2. #12

    По умолчанию

    bResult - ниразу не логического типа... многие библиотеки овен портировал свободно обращаясь с типами

    при отладке программы, делая горячие перезагрузки и пуски ПЛК, сокеты самостоятельно не закрываются, и при команде открытия создаются новые, возможные номера которых быстро кончаются... и получается программа работает, не работает.. с утра (после включения питания) опять работает - не работает .... поэтому вставьте блок закрытия сокетов, не морочясь проверкой результатов..

    кстати, при подключении через юзернет при отладке у вас на 3 сокета меньше....

  3. #13

    По умолчанию

    “и получается программа работает, не работает.. с утра (после включения питания) опять работает - не работает ....”

    Вот такая чача и происходит.

    “поэтому вставьте блок закрытия сокетов, не морочясь проверкой результатов..”

    Думал о этом, только немогу понять куда вставить закрытия сокетов, к событиям чтоль прикрутить?

    Спасибо.

  4. #14
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,248

    По умолчанию

    Цитата Сообщение от pavelrer Посмотреть сообщение
    Думал о этом, только немогу понять куда вставить закрытия сокетов, к событиям чтоль прикрутить?

    Спасибо.
    по биту питания из модуля статистики запускаете закрытие сокетов

  5. #15

    По умолчанию

    Модуль статистики – прикольная штука – спасибо

    Так ну вот вроде SysSockListen заработал
    Но теперь мой дискрипшен diSocket скачет раз в секунду то 1 то -1 других значений пока нет.
    Вот чего я и боялся, может я че не понимаю?

    Вот еще вопросик может я не все закрываю, я просто крою сокеты от 1..15.
    Как уже писали выше действительно ну о почему дескрипшин должен быть в этом диапазоне.
    Т.е вопрос простой как задавить все сокеты типа одной строкой?

    Понял что закрытия сокетов при старте нужно принять как есть и все.
    А в каких случаях еще необходимо закрывать сокеты?

    ... многие библиотеки овен портировал свободно обращаясь с типами
    Не могу понять почему так, ну до ладно подставляя места FALSE и TRUE - <0 и >0 все встает на свои места.

  6. #16
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,248

    По умолчанию

    я вообщето имел ввиду по заднему фронту питания закрывать сокеты, т.е. по выключению плк а не при старте
    почему меньше нуля, потому что когда писалась ОС плк, закралось неточность, поэтому и получается что фальш это -1, а всё остальное истина
    Я не пойму почему речь о каких то цифрах, закрывать Вы должны те сокеты, которые открыты и в проекте имеются на них дескрипторы

  7. #17

    По умолчанию

    TYPE SOCKET_OPTIONS :
    STRUCT
    bEnable: BOOL;
    bServer: BOOL;
    yOutAddr1: BYTE;
    yOutAddr2: BYTE;
    yOutAddr3: BYTE;
    yOutAddr4: BYTE;
    wOutPort: WORD;
    wMyPort: WORD;
    END_STRUCT
    END_TYPE

    TYPE SOCKET_CONDITION :
    (
    STC_EXPECT := 2#00000,
    STC_SETUP := 2#00001,
    STC_CONECT := 2#00010,
    STC_WORK := 2#00100,
    STC_BREAK := 2#01000,
    STC_CLOSE := 2#10000
    );
    END_TYPE


    FUNCTION_BLOCK fbSocket

    VAR_INPUT
    i_bWrite: BOOL;
    i_dwSize: DWORD;
    i_pBuffer: POINTER TO ARRAY [0..MB_BUFFERSIZE_] OF BYTE;
    i_pOptions: POINTER TO SOCKET_OPTIONS;
    END_VAR

    VAR_OUTPUT
    o_dnRes: DINT;
    o_eCondition: SOCKET_CONDITION;
    END_VAR

    VAR
    m_yDelay: BYTE;
    m_dnSocket: DINT := SOCKET_INVALID;
    m_SAddress: SOCKADDRESS;
    END_VAR



    (* cycle *)

    CASE o_eCondition OF

    STC_EXPECT:
    IF i_pOptions^.bEnable
    AND m_dnSocket = SOCKET_INVALID THEN
    m_dnSocket := SysSockCreate( SOCKET_AF_INET, SOCKET_STREAM, SOCKET_IPPROTO_IP );
    END_IF
    IF m_dnSocket <> SOCKET_INVALID THEN
    IF i_pOptions^.bServer THEN
    o_eCondition := STC_SETUP;
    ELSE
    o_eCondition := STC_CONECT;
    END_IF
    END_IF

    STC_SETUP:
    m_SAddress.sin_family := SOCKET_AF_INET;
    m_SAddress.sin_addr := SOCKET_INADDR_ANY;
    m_SAddress.sin_port := SysSockHtons( i_pOptions^.wMyPort );
    IF SysSockBind( m_dnSocket, ADR( m_SAddress ), SIZEOF( m_SAddress ) ) THEN
    o_eCondition := STC_CONECT;
    ELSE
    o_eCondition := STC_CLOSE;
    END_IF

    STC_CONECT:
    IF ( m_yDelay MOD 50 ) = 0 THEN
    IF i_pOptions^.bServer THEN
    o_dnRes := BOOL_TO_DINT( SysSockListen( m_dnSocket, 1 ) );
    ELSE
    m_SAddress.sin_family := SOCKET_AF_INET;
    m_SAddress.sin_port := SysSockHtons( i_pOptions^.wOutPort );
    m_SAddress.sin_addr := SHL( SHL( SHL(
    BYTE_TO_DWORD( i_pOptions^.yOutAddr1 ), 8 )
    OR BYTE_TO_DWORD( i_pOptions^.yOutAddr2 ), 8 )
    OR BYTE_TO_DWORD( i_pOptions^.yOutAddr3 ), 8 )
    OR BYTE_TO_DWORD( i_pOptions^.yOutAddr4 );
    o_dnRes := BOOL_TO_DINT ( SysSockConnect( m_dnSocket, ADR( m_SAddress ), SIZEOF( m_SAddress ) ) );
    END_IF
    IF o_dnRes = 0 THEN
    o_eCondition := STC_WORK;
    END_IF
    END_IF
    m_yDelay := m_yDelay + 1;

    STC_WORK:
    IF i_bWrite THEN
    o_dnRes := SysSockSend( m_dnSocket, i_pBuffer, i_dwSize, 0 );
    ELSE
    o_dnRes := SysSockRecv( m_dnSocket, i_pBuffer, i_dwSize, 0 );
    END_IF

    STC_BREAK:
    o_dnRes := BOOL_TO_DINT ( SysSockShutdown( m_dnSocket, 2 ) );
    IF o_dnRes = 1 THEN (* здесь не уверен, может быть > 0 методически грамотней *)
    o_eCondition := STC_CLOSE;
    END_IF

    STC_CLOSE:
    o_dnRes := BOOL_TO_INT( SysSockClose ( m_dnSocket ) );
    IF o_dnRes = 0 THEN
    m_dnSocket := SOCKET_INVALID;
    o_eCondition := STC_EXPECT;
    END_IF

    END_CASE

    конец FB

    + действие ReOpen: правой кнопкой на FB -> добавить действие
    если связь пропала делаем "сокет".ReOpen;

    (* reopen *)
    IF m_dnSocket <> SOCKET_INVALID THEN
    o_eCondition := STC_BREAK;
    END_IF

    кста. один сокет - одно подключение. такого понятия как "слушающий сокет" у сервера нет. в ПЛК "сервер" это просто "ведомый" или slave. он тупо отвечает на запросы клиента. поэтому если клиентов предполагается несколько то придецо создавать столько же сокетов серверов. с разными адресами (или портами) )
    насчет закрывать все сокеты до отключения ПЛК - фигня. открываю при включении и закрываю чтобы открыть вновь при потере связи. кста. по ходу при этом должен открыцо с таким же номером. иначе связь не востанавливаецо.

    дерзай. у меня все работает )
    Последний раз редактировалось lazy; 27.10.2013 в 15:38.

  8. #18

    По умолчанию

    Господа разжуйте мне пожалуйста следующие.

    Описание – что делаю.
    ОВЕН должен выступать как сервер, работать так: соединения.
    Если если готово, ждем пакет, отвечаем на него.
    Написал клиента, на другой системе, ONLINE на клиенте добился только
    Когда поменял в конфигурации задач выполнения сервера с T#10ms на T#100ms.
    Хотя T#10ms я честно содрал из екземпла.
    Так вот что надо делать после SysSockListen.
    На неделе был в Москве на выстовке, там программист мне сказал что надо сделать какойто
    aKnowledge ( принять соединения, разрешить обмен ). Ну а потом через прием передачу пакетов TCP.

    aKnowledge – что это? И с чем его едят?

    Ну или

    STC_WORK:
    IF i_bWrite THEN
    o_dnRes := SysSockSend( m_dnSocket, i_pBuffer, i_dwSize, 0 );
    ELSE
    o_dnRes := SysSockRecv( m_dnSocket, i_pBuffer, i_dwSize, 0 );
    END_IF

    i_bWrite – это что такое, не могу понять.

    Спасибо.

  9. #19

    По умолчанию

    сначала сокет нужно открыть. для этого скармливай ему настроенный SOCKET_OPTIONS пока o_eCondition не станет STC_WORK.
    "сокет"( i_pOptions := адрес на структуру SOCKET_OPTIONS );

    ну а потом хош читай хош пиши.
    вызов для чтения:
    "сокет"( i_bWrite := FALSE, i_pBuffer := адрес буфера, i_dwSize := длинна данных );
    для записи:
    "сoкет"( i_bWrite := TRUE, i_pBuffer := адрес буфера , i_dwSize := длинна данных );

    после вызова контролируй o_dnRes; Должен быть равным длинне данных.

    если ПЛК сервер. то он должен постоянно читать и прочитав какуюнть команду от ведомого должен ее выполнить. например передать данные или наоборот записать. Это уже протокол обмена. У модбаса например есть описанный протокол. Чота типа этого (это в буфере будет лежать при чтении с сокета) полностью в нете нарыть можно:


    байт 0: идентификатор транзакции - копируется сервером - обычно 0
    байт 1: идентификатор транзакции - копируется сервером - обычно 0
    байт 2: идентификатор протокола = 0
    байт 3: идентификатор протокола = 0
    байт 4: поле длины (старший байт) = 0 (так как все сообщения меньше 256)
    байт 5: поле длины (младший байт) = количество следующих байтов
    байт 6: идентификатор устройства (раньше "адрес SLAVE")
    байт 7: код функции MODBUS
    байт 8: данные, если требуется

    Можешь его использовать. А можешь свой написать )
    Последний раз редактировалось lazy; 05.11.2013 в 17:54.

  10. #20

    По умолчанию

    SOCKET_OPTIONS

    Вызываю после diSocket := SysSockCreate(SOCKET_AF_INET, SOCKET_STREAM, SOCKET_IPPROTO_TCP);
    Если diSocket не инвалид

    dwValue: DWORD:= 1;

    OpResult:=SysSockSetOption(diSocket, SOCKET_SOL, SOCKET_SO_REUSEADDR, ADR(dwValue), SIZEOF(dwValue));

    Что значит SysSockSetOption не то-что понять не могу, почитав доку даже додумать не смог! Что это?
    Содрал тупо из екземпла.

    Из доки
    SysSockSetOption
    Функция (из библиотеки SysLibSockets.lib) типа BOOL , вызывает функцию getsockopt операционной системы для задания определенных опций сокета. Детальное описание функции getsockopt дано в справочной системе соответствующей ОС. Возвращает TRUE при успешном окончании, иначе FALSE.

    Переменная Тип данных Описание
    diSocket DINT Дескриптор сокета, возвращаемый SysSockCreate (в Win32 параметр s)
    diLevel DINT Специфический уровень протокола (в Win32 параметр level)
    diOption DINT Имя опции. (в Win32 параметр optname) зависит от ОС
    diOptionValue DWORD Значение опции; для деактивации логических значений используется "0" (в Win32 параметр optval)
    diOptionLength DWORD Размер буфера значения опции (в Win32 параметр optlen)
    Что это?

    Специфический уровень протокола – это как – таймер, таймер времени, для отсчета временного диапазона, для задержки времени, если в вашей программе потребуется таймер. Внимание это таймер времени в формате времени и даты……Тут восход, закат и типы данных из Греции…..и.т.д – Непонятно! Такое впечатления что я с китайского перевел на итальянский потом на немецкий затем на иврит и потом на русский (ну и переводчики на русский работали в роснано).

    Можно пояснить, Что такое SysSockSetOption и все его трепуха кроме diSocket

    Далее еще раз

    STC_WORK:
    IF i_bWrite THEN
    o_dnRes := SysSockSend( m_dnSocket, i_pBuffer, i_dwSize, 0 );
    ELSE
    o_dnRes := SysSockRecv( m_dnSocket, i_pBuffer, i_dwSize, 0 );
    END_IF

    i_bWrite – это что такое, не могу понять, как изменяется.
    Ладно возможно туплю IF i_bWrite THEN что значит, не с чем не сравнивается?
    Ну и ELSE потом. Видимо енто BOOL – false или true?

    В общем возможно в данной структуре не понимаю как работает IF без сравнения
    Ну и в любом случаи не понимаю как, по какому признаку меняется i_bWrite
    Оно же i_bWrite: BOOL; в примере не нашел как меняется т.е всегда при старте true.

    Сори за дотошность (опыта = 0, дело сделать надо понимаючи).
    Курю исходники (екземплы) – понимаю все пошагово.

    Спасибо.

Страница 2 из 8 ПерваяПервая 1234 ... ПоследняяПоследняя

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •