Как установить время ожидания в Connect/ Send? ( as400 iseries v5r4, rpg)

Из этого руководства по сокету rpg мы создали клиент сокетов в rpg, который вызывает сокет java-сервера

Проблема в том, что блоки операций connect()/send() блокируются, и у нас есть требование, что если соединение / отправка не может быть выполнено в считанные секунды, скажем, мы должны просто зарегистрировать его и завершить.

Если я установлю сокет в неблокирующий режим (я думаю, с помощью fnctl), мы не до конца понимаем, как действовать, и не можем найти никакой полезной документации с примерами для этого.

Я думаю, что если я соединяюсь с неблокирующим сокетом, я должен сделать select(..., timeout), который сообщает нам, если соединение выполнено успешно и / мы можем отправить (в байтах). Но если мы отправим (в байтах) впоследствии, так как теперь это неблокирующий сокет (который будет возвращаться сразу после вызова), как я узнаю, что send () осуществил фактическую отправку байтов на сервер перед закрытием разъем?

Я могу использовать клиентский сокет в AS400 как процедуру Java или C, но я действительно хочу оставить его в простой программе RPG.

Кто-нибудь поможет мне понять, как это сделать, пожалуйста? Спасибо!

1 ответ

Решение

На мой взгляд, тот учебник по RPG, о котором вы упомянули, имеет небольшой недостаток. Я полагаю, что ваша путаница вызывает код следующего раздела:

...
Следовательно, мы обычно вызываем API send () следующим образом:

D miscdata        S             25A
D rc              S             10I 0

C                   eval      miscdata = 'The data to send goes here'
C                   eval      rc = send(s: %addr(miscdata): 25: 0)
c                   if        rc < 25
C*  for some reason we weren't able to send all 25 bytes!
C                   endif

...

Если вы читаете документацию send() вы увидите, что возвращаемое значение не указывает на ошибку, если оно больше -1, но в приведенном выше коде кажется, что произошла ошибка. Фактически, сумма возвращаемых значений должна равняться размеру буфера, предполагая, что вы продолжаете перемещать указатель в буфер, чтобы отразить то, что было отправлено. Посмотрите здесь в Beej's Guide по сетевому программированию. Возможно, вы также захотите взглянуть на книгу Ричарда Стивенса " Сетевое программирование UNIX", том 1, чтобы получить действительно подробные объяснения.

Что касается проблемы определения того, была ли последняя отправка раньше close() сделал фактическую отправку... хорошо, параграф выше объясняет, как определить, какая часть данных была отправлена. Тем не менее, призывая close() будет пытаться отправить все неотправленные данные, если SO_LINGER установлено.

fnctl() используется для управления блокировкой во время setsockopt() используется для установки SO_LINGER,

Используемая абстракция сетевых коммуникаций - это сокеты BSD. Существуют небольшие различия в реализациях в разных ОС, но, как правило, они довольно однородны. Это означает, что обычно можно использовать документацию, написанную для других ОС, для широкого обзора. Большую часть времени

Другие вопросы по тегам