2

I'm trying to receive a buffer through a TCP socket using the TServerSocket component (I'm maintaining a legacy application, so migrating to Indy or anything else is out of question for now).

I have implemented a method of the OnClientRead event that reads this buffer in a non-blocking socket (again, I cannot make drastic changes to this legacy application).

The function looks like this:

procedure TFrmMain.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Size: Integer;
  Bytes: TBytes;
begin
  Size := Socket.ReceiveLength;
  SetLength(Bytes, Size);
  Socket.ReceiveBuf(Bytes, Size);
end;

However, this gives me the following exception:

Asynchronous socket error 10053

If I change it to this:

procedure TFrmMain.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Size: Integer;
  Bytes: array[0..1024*256] of Byte;
begin
  Size := Socket.ReceiveLength;
  Socket.ReceiveBuf(Bytes, Size);
end;

It works. However, the dynamic approach is more adequate to my problem domain.

What could be causing this? My objective is to read a binary buffer through a TCP socket with this component.

Thanks in advance.

ivarec
  • 2,542
  • 2
  • 34
  • 57

1 Answers1

2

The first parameter of ReceiveBuf is an untyped var parameter. It needs direct access to the place it's going to start writing.

When you pass it a dynamic array, it will overwrite the dynamic-array variable itself instead of the contents of the array. Pass a reference to the first element of the array instead of a reference to the variable:

Socket.ReceiveBuf(Bytes[0], Size);

That syntax will work with non-dynamic arrays, too. In that case, a reference to the first element is the same as a reference to the variable itself.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • This still does not explain why mysterious error 10053 happen instead of the A/V from the overwritten stack. @haole, i know the fix on the [delphi] side, but immediate cause of 10053 remains mystery for me too. – OnTheFly Jan 20 '12 at 19:18
  • Stack corruption can lead to all sorts of things, @User. Since the stack of this function is small, maybe ReceiveBuf also ends up overwriting *its own* stack. – Rob Kennedy Jan 20 '12 at 19:55
  • @user539484 I read somewhere in the documentation that error 10053 happens when the socket is closed "ungracefully" and that Delphi's sockets might do that if an exception happens during the reception of the data. Could explain it... I call ReceiveBuf, an exception is thrown and the socket gets messed up. – ivarec Jan 20 '12 at 20:12
  • Stack corruption is a random process, probability to reproduce some specific misbehaviour is negligible. @haole, your hypothesis leads to an idea to look at source, this class might assume WSAECONNABORTED for random unspecific errors. – OnTheFly Jan 20 '12 at 21:17