Socket.ReceiveBuf - Sprawdzanie zawartości

0

Witam,

W swoim programie tworzę funkcję rozmowy głosowej poprzez gniazdka.
Korzystam z komponentu WaveAudio do Delphi XE3.

Samo odbieranie dźwięku i przesyłanie działa i wygląda to mniej więcej tak:

Serwer:

procedure TfrmMain.TcpServerAccept(Sender: TObject; Socket: TCustomWinSocket);
type
  TWaveFormatInfo = packed record
    WaveFormatSize: Integer;
    WaveFormat: TWaveFormatEx;
  end;
var
  WFI: TWaveFormatInfo;
  ClientName: String;
begin
  SetPCMAudioFormatS(@WFI.WaveFormat, LiveAudioRecorder.PCMFormat);
  WFI.WaveFormatSize := SizeOf(WFI.WaveFormat);
  Socket.SendBuf(WFI, SizeOf(WFI));

  ClientName := FormatAddress(Socket.RemoteHost, Socket.RemoteAddress);

  if MyVoiceCall.Busy then
  begin
    Socket.SendText('@BUSY');
  end
  else
  begin
    MyVoiceCall.IsServer := True;
    MyVoiceCall.Busy := True;

    if not Assigned(frmVoiceCall) then
    begin
      Application.CreateForm(TfrmVoiceCall, frmVoiceCall);


      Socket.SendText('@CALLING');

      frmVoiceCall.VoiceCallFrom(ClientName);
      frmVoiceCall.Show;
    end
    else
      frmVoiceCall.Show;

  end;
end;

procedure TfrmMain.TcpServerClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Text: AnsiString;
begin
  SetString(Text, nil, Socket.ReceiveLength);
  Socket.ReceiveBuf(PAnsiChar(Text)^, Length(Text));

  if Text = 'READY' then
    Socket.Data := Self;
end;

Klient:

procedure TfrmMain.TcpClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  ClientName: String;


  WaveFormatSize: Integer;
  Data: Pointer;
  DataSize: Integer;

  Text: AnsiString;
begin
  {SetString(Text, nil, Socket.ReceiveLength);
  Socket.ReceiveBuf(PAnsiChar(Text)^, Length(Text));
       }


  ClientName := FormatAddress(Socket.RemoteHost, Socket.RemoteAddress);
  ClientName := StringReplace(ClientName, '.systemeg.internal', '', [rfReplaceAll]);

  {
  if Text = '@CALLING' then
  begin

  end
  else if Text = '@BUSY' then
  begin

  end
  else if pos('@ACCEPTED', Text) > 0 then
  begin
    Text := StringReplace(Text, '@ACCEPTED', '', [rfReplaceAll]);
    MyVoiceCall.ClientName := ClientName;
    MyVoiceCall.Calling := True;
  end;

  if MyVoiceCall.Calling then
  begin   }

    try
      if not LiveAudioPlayer.Active then
      begin
        Socket.ReceiveBuf(WaveFormatSize, SizeOf(WaveFormatSize));
        ReallocMem(WaveFormat, WaveFormatSize);
        try
          Socket.ReceiveBuf(WaveFormat^, WaveFormatSize);
        except
          ReallocMem(WaveFormat, 0);
          raise;
        end;
        LiveAudioPlayer.Active := True;
      end
      else
      begin
        Sleep(0); // giving chance to the player thread for using the audio buffer
        DataSize := Socket.ReceiveLength;
        if BlockAlign > 1 then
          Dec(DataSize, DataSize mod BlockAlign);
        if DataSize <> 0 then
        begin
          Data := AudioBuffer.BeginUpdate(DataSize);
          try
            Socket.ReceiveBuf(Data^, DataSize);
          finally
            AudioBuffer.EndUpdate;
          end;
        end;
      end;
    except
      tcpClient.Active := False;
      Application.HandleException(Self);
    end;
 // end;
end;

Chciałbym, aby cała funkcja TRY EXCEPT była wykonywana w zależności od zawartości otrzymanych danych. Tzn chcę kontrolować odbiór poprzez polecenia np.

Łączymy się z serwerem:

  1. Klient wysyła polecenie do serwera '@CALLING'
  2. Serwer sprawdza, czy nie prowadzimy już rozmowy z kimś innym poprzez zmienną w rekordzie MyVoiceCall.Busy: boolean;
  3. Jeżeli nie, to pokazujemy u klienta okienko dzwonienia a na serwerze okno informujące, że ktoś dzwoni z opcją odrzucenia lub przyjęcia rozmowy. W tym czasie klient jak i serwer ustawiają zmienną Busy na True, aby odrzucać pozostałych klientów, którzy będą chcieli w tym samym czasie dzwonić, i wysyła do nich polecenie '@busy', które ich o tym zdarzeniu powiadomi np. "Klient obecnie prowadzi rozmowę".
  4. Dopiero, gdy kliknę Odbierz, do serwera leci polecenie '@ACCEPTED' i dopiero wtedy powinien wykonywać się cały Try Except, ale chciałbym też wiedzieć, kiedy klient się rozłączy klikając w Czerwoną słuchawkę, wówczas wyślę polecenie '@CALLEND', które rozłączy obie strony.
    Nie jestem specem z gniazdek i proszę o pomoc, w jaki sposób kontrolować zawartość ReceiveBuff.
    Jak próbowałem
var
  Text: AnsiString;
begin
  SetString(Text, nil, Socket.ReceiveLength);
  Socket.ReceiveBuf(PAnsiChar(Text)^, Length(Text));
       
  if Text = '@CALLING' then
  begin

  end
  else if Text = '@BUSY' then
  begin

  end
  else if pos('@ACCEPTED', Text) > 0 then
  begin
    Text := StringReplace(Text, '@ACCEPTED', '', [rfReplaceAll]);
    MyVoiceCall.ClientName := ClientName;
    MyVoiceCall.Calling := True;
  end;

a następnie

if MyVoiceCall.Calling then
  begin   

    try
      if not LiveAudioPlayer.Active then
      begin
        Socket.ReceiveBuf(WaveFormatSize, SizeOf(WaveFormatSize));
        ReallocMem(WaveFormat, WaveFormatSize);
        try
          Socket.ReceiveBuf(WaveFormat^, WaveFormatSize);
        except
          ReallocMem(WaveFormat, 0);
          raise;
        end;
        LiveAudioPlayer.Active := True;
      end
      else
      begin
        Sleep(0); // giving chance to the player thread for using the audio buffer
        DataSize := Socket.ReceiveLength;
        if BlockAlign > 1 then
          Dec(DataSize, DataSize mod BlockAlign);
        if DataSize <> 0 then
        begin
          Data := AudioBuffer.BeginUpdate(DataSize);
          try
            Socket.ReceiveBuf(Data^, DataSize);
          finally
            AudioBuffer.EndUpdate;
          end;
        end;
      end;
    except
      tcpClient.Active := False;
      Application.HandleException(Self);
    end;
  end;

To program się zawiesza. Tak jak by nie można było wykonać

Socket.ReceiveBuff(PAnsiChar(Text)^, Length(Text));

a linijkę niżej Socket.ReceiveBuff(WaveFormatSize, SizeOf(WaveFormatSize));


<span style="color: gray"><i>`dodanie znaczników wypunktowania`</i> - @{furious programming}</span>
0

Poradziłem sobie, wymyśliłem sposób na obejście.

1 użytkowników online, w tym zalogowanych: 0, gości: 1