I am trying to send a 4063 bytes AMR file (just for testing) from my CentOS VPS
nc IP 45500 < sample.amr
But when the application receives it just show a cutted data:
1448: #!AMR-WB
Ô_Æ ÅѤm^8E•Ì^^ìÖõ¾_€°
2617:
The strange thing is: If I edit the AMR file and remove the marked char:
And send again the same AMR file I receive:
1448: #!AMR-WB
Ô_Æ ÅѤm^8E•Ì^^ìÖõ¾_€°ÀžH¯ë2Çc oÚÖɾøy$Ý
2616: ¢Khw^è“ʺ\?¬šJ£<é<'
.. more data, specifically up to the next NUL char
This is the code for my Socket onClientRead
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
received,a: string;
size,i: Integer;
AnsiStr: String;
Bytes: array[0..2048*256] of Byte;
begin
Size := Socket.ReceiveLength;
Socket.ReceiveBuf(Bytes[0], Size);
SetString(AnsiStr, PAnsiChar(@Bytes[0]), Size);
received := IntToStr(Size)+': '+AnsiStr;
Memo1.Lines.Add(received);
Memo1.Lines.Add(' ');
end;
I believe the SetString
command is causing this, but not sure how to receive the whole DATA. I just want to receive the whole file and copy it to a new AMR file on my side.
Extra: The file that I am trying to send from my server to my computer is located here: http://techslides.com/demos/samples/sample.amr
There are two main reasons why your code doesn't work:
you are using a Unicode version of Delphi, so the string
type maps to UnicodeString
, instead of AnsiString
like you are expecting.
internally, the TMemo.Lines.Add()
method passes the string to the TMemo
window using the EM_REPLACESEL
message, which treats the input string as null-terminated. That is why your file content gets truncated at nul
"characters".
As other people said in comments, you are trying to display binary data as if it were text, but it is not text. Save the raw binary data as-is to an actual file on your HDD instead. If you want to display the file bytes in your UI, display them in a text-safe format, such as hex.
Try something more like this:
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Socket.Data := TFileStream.Create('<some path>\sample.amr', fmCreate);
end;
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
TFileStream(Socket.Data).Free;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
Size: Integer;
Bytes: TBytes;
Received: string;
begin
Size := Socket.ReceiveLength;
if Size < 1 then Exit;
SetLength(Bytes, Size);
Size := Socket.ReceiveBuf(Bytes[0], Size);
if Size < 1 then Exit;
TFileStream(Socket.Data).WriteBuffer(Bytes[0], Size);
SetLength(Received, Size*2);
BinToHex(Bytes[0], PChar(Received), Size);
Memo1.Lines.Add(IntToStr(Size) + ': ' + Received);
Memo1.Lines.Add(' ');
end;