Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Первый раз работа по сети


Автор: sunnmas 2.4.2011, 02:48
Имею Delphi 10Lite

Имеется платка, которая подсоединяется к компу по усб, эмулируя ком порт. Работать с ней умею. есть офис с несколькими компами, объединенных в локалку. Есть приложение, которое может использоваться с данной платкой. Сейчас если кто-то хочет поработать должен брать плату и подсоединять к своему компу. Так она кочует с компа на комп. Нужно сделать так, чтобы она была подключена к какому либо компу. На этом компе запущен сервер, к которому будут подключаться другие через tcp и работать с железом.

В этой версии дельфи есть компоненты TTCPServer/Client. Встречаю скудные примеры по работе с данными компонентами. Все они сводятся к тому, что в обработчике события OnAccept сервера читаем сообщение от клиента и шлем ему ответ, далее выход из обработчика - приводит к закрытию соединения. Нужно сделать как-то так чтобы после подключения клиента запускался цикл ожидания команд от клиента для платы и полученные команды отсылались ей, принимались данные от платы и обратно отправлялись ответы от нее клиентам(клиент использует те же команды, как если бы он общался через ком порт, только шлет и принимает их по сети). Серверу должен быть не важен характер данных для того чтобы можно было менять протокол оконечный софт - плата без затрагивания кода сервера в будущем. Он просто принимает, что прислал клиент и пишет в плату, читает ответ и передает назад. Обычно один сеанс связи клиент - плата состоит из множества команд обмена. Поэтому цикл сервера должен быть готов принимать множество пакетов и отсылать ответы платы обратно. Так же как то нужно прерывать этот цикл с помощью клиента. Например клиент делает дисконнект и сервер выходит из цикла, ожидая следующего подключения клиента - следующего сеанса, состоящего из множества команд. Так же выход из цикла по таймауту. Реально это замутить в обработчике OnAccept? Не могли бы вы набросать примерный вид этого обработчика. Надеюсь на посильную помощь. Спасибо

Автор: kami 2.4.2011, 12:21
Попробуй воспользоваться http://forum.vingrad.ru/topic-290376/view-findpost/p-2090440.html (не сочти за саморекламу, но работа с "низкоуровневыми" сетевыми компонентами - достаточно нетривиальная задача).

Автор: sunnmas 2.4.2011, 13:41
далеко от моего вопроса. Но все равно спасибо

Автор: Akella 2.4.2011, 17:06
Цитата(sunnmas @  2.4.2011,  02:48 Найти цитируемый пост)
Имею Delphi 10Lite

шо это за хня? варез какой-то? здесь варез нельзя обсуждать.

Автор: sunnmas 2.4.2011, 18:05
Цитата(Akella @ 2.4.2011,  17:06)
Цитата(sunnmas @  2.4.2011,  02:48 Найти цитируемый пост)
Имею Delphi 10Lite

шо это за хня? варез какой-то? здесь варез нельзя обсуждать.

на сколько мне известно это бесплатная студенческая версия порезанная. поэтому и юзаю ее, т.к. в офисе пописываю. Но вообще предыдущее высказывание не понятно мне. Да и не по теме

Автор: kami 2.4.2011, 21:46
Цитата(sunnmas @  2.4.2011,  13:41 Найти цитируемый пост)
далеко от моего вопроса.

Почему?
Я предлагаю воспользоваться для передачи по сети готовым решением, в котором учитываются многие проблемы, возникающие при использовании TCP. На "перворазном" этапе работы подобные "неявности" и "недоговоренности" приведут к неверному проектированию программы, заставят использовать ненужные костыли и так далее и тому подобное. Причем - на этапе тестирования, когда сервер и клиент расположены на одном компьютере, неучтенные проблемы однозначно не будут выявлены. А когда программа перейдет в стадию апробации на рабочих местах, начнут появляться всякие глюки, причину которых понять будет весьма непросто.

Автор: Keeper89 2.4.2011, 22:51
Цитата(sunnmas @  2.4.2011,  18:05 Найти цитируемый пост)
на сколько мне известно это бесплатная студенческая версия порезанная. поэтому и юзаю ее, т.к. в офисе пописываю. 

какая какая версия? =) http://en.wikipedia.org/wiki/Embarcadero_Delphi#Versions она есть?

Автор: cat512 3.4.2011, 14:31
Цитата

Реально это замутить в обработчике OnAccept? Не могли бы вы набросать примерный вид этого обработчика

Во-первых, скажу что неплохо внимать советам которые дают на форуме опытные камрады. Всё, о чём писал kami, является действительно актуальным!. 
Во-вторых, если дейстыительно хочется изобретать велосипед, то проблемы тоже не вижу. Например, берём любую демку чата, из состава делфи 5-7, и смотрим как реализован обработчик OnAccept.

Автор: sunnmas 11.4.2011, 22:55
прогресс вреде есть с компанентами инди 10.

Но и проблемы тоже имеются. 

Вот рабочий кусок кода (он в сокращении выложен. оставлены только ключевые моменты):

клиент:
   TcpCli:=TIdTCPClient.Create(nil);
  TcpCli.Port:=3006;
  TCPCli.ReadTimeout:=1000;
  TCPCli.UseNagle:=false;
...
    TCPCli.Host:=NOD;
    TcpCli.Connect;
    if not TcpCli.Connected then
    begin
      LOG.WriteString('  TcpCli not connected to server'+#13#10);
      exit;
    end;
...
 try
    TCPCli.IOHandler.WriteBufferOpen;
    TCPCli.IOHandler.Write(FWrBuf); -шлю 1 байт
    TCPCli.IOHandler.WriteBufferClose;
  except
    on E: EIdException do
    begin
      LOG.WriteString('WriteBuffer failed. exception: '+E.Message+#13#10);
      Result:=false;
    end
    else
    begin
      LOG.WriteString('WriteBuffer failed. Fuck, Shit!'+#13#10);
      Result:=false;
    end;
  end;

сервер
procedure TMainForm.IdTCPServerExecute(AContext: TIdContext);
var buf: array[0..100] of byte;
begin
  try
    with AContext.Connection do
    begin
      try
        Dongle.FWrBuf.Clear;
        try
          IOHandler.ReadStream(Dongle.FWrBuf,1); принимаю 1 байт
        except
        end;

        if Dongle.FWrBuf.Size>0 then
        begin
         //пишем данные в плату
          if not Dongle.WriteBuffer then
            exit;

        end;

      //читаем данные из платы
        Dongle.FRdBuf.Clear;
        Dongle.ReadBuffer;
        if Dongle.FRdBuf.Size>0 then
        begin
         //отправляем ответ от платы клиентской программе
          IOHandler.WriteBufferOpen;
          IOHandler.Write(Dongle.FRdBuf);
          IOHandler.WriteBufferClose;
          exit;
        end;

      except
      end;
    end;
  finally
  end;
end;

Вот так все работает


Но нужно двигаться дальше. Отсылать серваку не 1 байт, а произвольное их количество
Для этого на сервере изменяю так:
...
with AContext.Connection do
    begin
      try
        Dongle.FWrBuf.Clear;
       IOHandler.ReadTimeout(50);
        try
          IOHandler.ReadStream(Dongle.FWrBuf);
        except
        end;
...

ставлю на сервере usenagle=false

при этом IOHandler.ReadStream не зависает, но и не принимает никаких данных (от клиента все так же шлю пока 1 байт)


Недогоняю пока в чем проблема. Подскажите?

Автор: sunnmas 11.4.2011, 23:29
Кстати при использовании TIdLOGFile

у клиента:
Sent 12.04.2011 0:24:31: 

у сервера:
Recv 12.04.2011 0:24:31: 


там после двоеточия дет квадратик(типо неотображаемый символ я полагаю)

По сему на сервер данные поступают, но в поток Dongle.FWrBuf этот байт не записывается!

как быть?

Автор: Akella 14.4.2011, 10:35
sunnmas, а что, кнопку КОД не судьба использовать? 
http://forum.vingrad.ru/forum/topic-126445.html

Добавлено через 3 минуты и 21 секунду
Цитата(sunnmas @  11.4.2011,  22:55 Найти цитируемый пост)
Отсылать серваку не 1 байт, а произвольное их количество

нужно ведь как-то серверу сообщить, сколько ты байт отправляешь?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)