Конференция "Сети" » TSeverThead, TServerSocket [D7, WinXP]
 
  • dozcent © (10.08.08 23:22) [20]
    Как реализовать этот аккомулятор и машину состояния?
  • dozcent © (10.08.08 23:26) [21]
    Вы имеете в виду такую конструкцию...

    var
     ac, readlen : integer;
    begin
     FillChar( fRequest, REQUESTSIZE, 0 );
     ac := 0;
     repeat
       readlen := fSocketStream.Read( fRequest[ac],1024 );
       ac := ac+readlen;
     until ( readlen = 0 ) or ( ac = REQUESTSIZE );
    end;

  • dozcent © (10.08.08 23:31) [22]
    Даже для трёх байт такое надо делать?
  • Сергей М. © (10.08.08 23:38) [23]

    > Даже для трёх байт такое надо делать?


    Да, даже для двух.

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

    Так что готовь тару объемом в бутыль и жди пока она наполнится, коль договорились)

    Время наполнения и порции, коими наполнение должно происходить, в общем случае тебе не известно)
  • Сергей М. © (10.08.08 23:45) [24]

    > FillChar( fRequest, REQUESTSIZE, 0 );


    А это вообще нафиг не нужно.
  • dozcent © (10.08.08 23:53) [25]
    А в этой функции лучше ставить минимум или максимум?
      readlen := fSocketStream.Read( fRequest[ac],1024 );
    Тобишь 1 или 17?
  • Slym © (11.08.08 05:33) [26]
    приведи протокол устройтсва...
  • Slym © (11.08.08 06:16) [27]
    dozcent ©   (10.08.08 23:26) [21]
    Вы имеете в виду такую конструкцию...

    почти
    procedure ReadBufferEx(SocketStream:TWinSocketStream;var Buffer; Count: Longint);
    var
     PBuffer:PByte;
     Readed:integer;
    begin
     PBuffer:=@Buffer;
     while Count>0 do
     begin
       readed:=SocketStream.Read(PBuffer^,Count);
       Dec(Count,readed);
       Inc(PBuffer,readed);
     end;
    end;

  • Slym © (11.08.08 06:40) [28]
    Должно получиться чтото типа этого:
    procedure TServerClientThreadEx.ClientExecute;
    var
     SocketStream:TWinSocketStream;
     Packet:array[0..16] of byte;
     Packet2:array[0..2] of byte;
    begin
     try
       SocketStream:=TWinSocketStream.Create(ClientSocket, 30);
       try
         while (not Terminated) and (ClientSocket.Connected) do
         begin
           if not SocketStream.WaitForData(SocketStream.TimeOut) then
            raise Exception.Create('Protocol: timeout');

           ReadBufferEx(SocketStream,Packet,SizeOf(Packet));
           LogServerEvents('Packet Readed');
           if ClientSocket.ReceiveLength<>0 then
             LogServerEvents('Packet fully Readed, but some socket data still avaliable... Error?');

           SetString(IMEI,Packet,SizeOf(Packet));
           ConnectToDb;
           try
             if DeviceInDB then
             begin
              if UpdateTime then
              begin
                CreatePackage;
                SendingMessage;
                if not SocketStream.WaitForData(SocketStream.TimeOut) then
                  raise Exception.Create('Protocol: timeout');

                ReadBufferEx(SocketStream,Packet2,SizeOf(Packet2));
                LogServerEvents('Packet2 Readed');
                if ClientSocket.ReceiveLength<>0 then
                  LogServerEvents('Packet2 fully Readed, but some socket data still avaliable... Error?');

                if Packet2[2]>=MessCount then
                begin
                  SetUpUpdateTime;
                  LogConnection(1);
                end else
                begin
                  LogConnection(2);
                end;
              end else
              begin
                LogConnection(3);
              end;
             end else
             begin
              SendingMessageToNewDevice;
              LogConnection(4);
             end;
           finally
             DisconnectFromDb;
           end;
           LogServerEvents('We finish Protocol loop');
         end;
         LogServerEvents('We break IO loop');
       finally
         SocketStream.Free;
       end;
     except
       on e: exception do
         LogError('Error: '+e.Message);
     end;
    end;

  • Сергей М. © (11.08.08 08:27) [29]

    > Тобишь 1 или 17?


    Читай ровно столько, сколько осталось прочитать из этих 17-ти ожидаемых байт

    запросил к чтению 17, фактически прочитал 2, осталось прочитать 15
    запросил  к чтению 15, фактически прочитал 5, осталось прочитаь 10
    запросил  к чтению 10, фактически прочитал 1, осталось прочитаь 9
    запросил  к чтению 9, фактически прочитал 4, осталось прочитаь 5

    и т.д. до тех пор пока "осталось прочитаь" не станет равным 0

    Эта логика применима во всех случаях, когда заранее известен размер очередного инф.сообщения, ожидаемого к приему от партнера на данном этапе исполнения протокола инф.обмена.
 
Конференция "Сети" » TSeverThead, TServerSocket [D7, WinXP]
Есть новые Нет новых   [134432   +20][b:0][p:0.004]