Конференция "Сети" » Connect WriteBuffer Disconnect
 
  • REAn (09.02.12 23:08) [0]
    Привет, коллеги
    Пытаюсь сделать передачу данных на Indy 9 от клиента к серверу.
    Код по смыслу такой:

    Client.Connect;
    Client.WriteBuffer(Data, Count, True{Forced write});
    Client.Disconnect;

    Работает эта схема не на всех машинах. Стабильно работает, если добавить Sleep() перед Disconnect. Т.е. данные не успевают приниматься сервером перед дисконнектом. Как можно избежать такой ситуации не используя Sleep()?
  • FireMan_Alexey © (10.02.12 00:24) [1]
    WriteBuffer это функция которая возвращает кол-во отправленных данных! А ТСР не гарантирует, что он сразу может послать Count байт!
  • REAn (10.02.12 00:48) [2]
    Байт там мало (примерно 15), все нормально отсылается. Проблема в том, что данные не доходят до того как соединение закрывается. Как это физически реализовано не знаю, но на принимающей стороне данных в буфере нет. Пытался выгребать их оттуда с помощью ReadFromStack.
  • Anatoly Podgoretsky © (10.02.12 10:22) [3]
    > REAn  (09.02.2012 23:08:00)  [0]

    Попробуй FlushWriteBuffer
  • REAn (10.02.12 11:34) [4]
    Я так понимаю FlushWriteBuffer эффективен, когда он есть. Т.е. вызвано что то вроде OpenBuffer. Я на самом деле и его попробовал, но он первый раз отрабатывает, а потом выдает Access Violation. Вариант с буферизацией (openbuffer write flush close disconnect) так же работает как и первый.
    Кроме того последний параметр WriteBuffer намекает, что оно должно тут же и отправить данные.
  • Anatoly Podgoretsky © (10.02.12 11:52) [5]
    Такая функция в Инди есть. Более того даже в твоем тексте
    Client.WriteBuffer(Data, Count, True{Forced write});


    Осталось посмотреть описание функции в справке.
  • REAn (10.02.12 13:37) [6]
    Я собственно ее и использовал. Не работает без задержки.
  • REAn (10.02.12 13:40) [7]
    Anatoly, не держите людей за идиотов. Я и справку посмотрел и исходники порыл уже и интернет (народ с этой проблемой тоже сталкивался). В девятом Indy на сервере ReadLn реализован так, что Disconect там обрабатывается раньше чем ReadFromStack. Можно попытаться переписать эту функцию, но возможно есть какие то другие варианты.
  • REAn (10.02.12 13:55) [8]
    Впрочем ReadLn переписать тоже не поможет, т.к. CheckForDisconnect и в ReadFromStack вызывается. Т.е. если наступило событие Disconnect, то уже нет смысла читать что либо - Handle сокета потерян и данные видимо тоже.
  • REAn (10.02.12 16:33) [9]
    Утомился бороться с этой проблемой, сделал вариант без немедленного разъединения. Всем спасибо за помощь.
  • Дмитрий Белькевич (10.02.12 19:10) [10]
    По хорошему - нужно какую-то синхронизацию с приёмником думать, какую-то обратную связь. Приёмнику послали что - приемник ответил что-то, синхронно с ответом отвалились. Если приёмник свой, конечно, и протокол позволяет.
  • REAn (10.02.12 20:23) [11]
    Там данные постоянно посылаются так что пользы от такой обратной связи мало - даже если данные не дошли они уже никому не нужны. Протокол к тому же сложновато переделать - нужно совместимость тянуть.
  • Сергей М. © (11.02.12 16:41) [12]

    > REAn


    Идешь сюда

    http://www.interface.ru/home.asp?artId=22678

    и куришь
    SO_LINGER

  • REAn (11.02.12 19:26) [13]
    Спасибо, почитаю. Я уже натыкался на эту загадочную штуку в исходниках Indy.
  • REAn (11.02.12 20:45) [14]
    В явном виде в Indy 9 это не реализовано. По умолчанию не знаю что стоит. Кому то может быть полезна еще функция SetNagleOpt, которая отключает или включает алгоритм Нагла.
  • Сергей М. © (11.02.12 22:36) [15]

    > В явном виде в Indy 9 это не реализовано


    Реализуй ручками, в чем проблема-то ?
    Хэндл гнезда же доступен
  • Сергей М. © (11.02.12 22:36) [16]

    > может быть полезна еще функция SetNagleOpt, которая отключает
    > или включает алгоритм Нагла


    Ничем она не полезна в дан.случае.
  • REAn (12.02.12 01:09) [17]
    ok, попробую
 
Конференция "Сети" » Connect WriteBuffer Disconnect
Есть новые Нет новых   [134435   +17][b:0][p:0.001]