0

I'm having problems trying to use OnUDPRead Event of TIdUDPServer to read broadcast Data sent from a IdUDPClient Client I created. I've tried using the examples shown in the following questions but to no avail.

How can I send a broadcast message in Delphi

Reading data with TIdUDPServer

I'm able to bind TIdUDPServer to the port I specify:

procedure TForm1.Button1Click(Sender: TObject);
begin
  IdUDPServer1.BroadcastEnabled := True;
  IdUDPServer1.DefaultPort := StrToInt(edit2.Text);
  IdUDPServer1.Bindings.Add.IP := '0.0.0.0';
  //IdUDPServer1.ThreadedEvent:=True;
  IdUDPServer1.Active := True;
end;

IdUDPServer1UDPRead is triggered successfully showing that the UDP Server is working, but I get an exception at this line -> DataStringStream.CopyFrom(AData, AData.Size);

Exception:Access violation at address 004BA415 in module 'IndyUDPReceiver.exe'. Read of address 74736574

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject;
  AData: TStream; ABinding: TIdSocketHandle);
var
  DataStringStream: TStringStream;
  msg: string;
begin
  try
    DataStringStream := TStringStream.Create('');
    try
      DataStringStream.CopyFrom(AData, AData.Size);
      msg := DataStringStream.DataString;
      Memo1.Lines.Add(msg);
    finally
      DataStringStream.Free;
    end;
  except
    on E: Exception do
    begin
      Memo1.Lines.Add('Exception:' + E.Message);
      DataStringStream.Free;
    end;
  end;
end;

I've uploaded the full Client and Server to: http://www.2shared.com/file/5SRweGIa/Indy_UDP.html

Grateful for any pointers. :)

Community
  • 1
  • 1
Joshua
  • 1,709
  • 2
  • 24
  • 38
  • Obviously an attempt is made to read memory that cannot be read. Exactly what part of the above code results in that. Which object cannot be read? You'll need to use the debugger, and possibly the asm debugger to find out. – David Heffernan Sep 22 '12 at 19:01
  • Yes, the exception was encountered at this line -> DataStringStream.CopyFrom(AData, AData.Size); *** Project IndyUDPReceiver.exe raised exception class EAccessViolation with message 'Access violation at address 004BA415 in module 'IndyUDPReceiver.exe'. Read of address 74736574'. – Joshua Sep 23 '12 at 16:20
  • Which object cannot be read? Use cpu view to debug asm. – David Heffernan Sep 23 '12 at 19:31
  • Hi David, here's what I got - http://imageshack.us/a/img12/3053/capturewy.jpg – Joshua Sep 24 '12 at 02:42
  • on which line is the av? – David Heffernan Sep 24 '12 at 02:57

1 Answers1

2

Did you, by chance, upgrade your project from an older version of Delphi and/or Indy, and forget to check your event handlers for signature changes? The TIdUDPServer.OnUDPRead event stopped using TStream for its AData parameter a long time ago. It was switched to using TIdBytes instead:

procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
var
  msg: string;
begin
  msg := BytesToString(AData, Indy8BitEncoding);
  Memo1.Lines.Add(msg);
end;

A few weeks ago, we had to change the AData parameter for XE3 to finally address an RTTI incompatibility between Delphi and C++ in all 2009+ versions:

procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: array of Byte; ABinding: TIdSocketHandle);
var
  msg: string;
begin
  msg := BytesToString(AData, Indy8BitEncoding);
  Memo1.Lines.Add(msg);
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    Only if the event handler were being assigned in code at runtime. If the event handler was written in an older version and assigned at designtime, then an upgrade were performed, the IDE is not likely to validate the pre-existing assignment and happily keep using it even though the signature does not match anymore. It is exactly that lack of validation that led to the creation of the `STRINGCHECKS` directive in Delphi 2009-2010 during the Unicode migration, when string-based events switched from Ansi to Unicode. The RTL had to be updated to handle mismatched event handlers, especially in C++. – Remy Lebeau Sep 24 '12 at 03:07
  • OK, that makes a lot of sense. – David Heffernan Sep 24 '12 at 03:13
  • 1
    So, in this case, if the event handler signature were mismatched but the IDE still accepted it (since DFMs are not type-safe), the `AData` parameter would be getting a `TIdBytes` at runtime but the code would be interpreting it as a `TStream` and cause this type of exception when accessing the wrong kind of memory. – Remy Lebeau Sep 24 '12 at 03:13