Lazarus/FreePascal,Synapse将文件发送到TCPBlockSocket

Ant*_*sov 3 delphi freepascal apache-synapse netcat lazarus

我试图制作一个模拟nc(netcat)工具.打开文件并将其发送到TCP套接字.

客户(发件人)方

procedure TForm1.SpeedButton3Click(Sender: TObject);
var Client:TTCPBlockSocket;
    FS: TFileStream;
begin
  Client:=TTCPBlockSocket.Create;
  Client.RaiseExcept:=True;
  Client.Connect('192.168.1.95','9999');
  FS:=TFileStream.Create('/tmp/test_print.pdf',fmOpenRead);
  FS.Position:=0;
  Client.SendStream(FS);
  FS.Free;
  Client.CloseSocket;
  Client.Free;
end;        
Run Code Online (Sandbox Code Playgroud)

服务器(接收方)方面

nc -l 192.168.1.95 9999> test.pdf

运行后我得到test.pdf但md5sum无效

fe2e5d86acd267ca39a9c15c456e1be0  /tmp/test_print.pdf
34d755aa81d72f525a5e691e98bed283  test.pdf
Run Code Online (Sandbox Code Playgroud)

尺寸也不同

-rw-rw---- 1 user1 DomainUsers 46444 ???  8 17:11 /tmp/test_print.pdf
-rw-r--r-- 1 user1 DomainUsers 46448 ??? 11 15:40 test.pdf
Run Code Online (Sandbox Code Playgroud)

我做错了什么?我的错误在哪里?

ps test.pdf开头超出4个字节(6c,b5,00,00)

[user1@pandora6 /tmp]$ hexdump -C test.pdf | head -5
00000000  6c b5 00 00 25 50 44 46  2d 31 2e 34 0a 25 c7 ec  |l...%PDF-1.4.%..|
00000010  8f a2 0a 34 20 30 20 6f  62 6a 0a 3c 3c 2f 4c 69  |...4 0 obj.<</Li|
00000020  6e 65 61 72 69 7a 65 64  20 31 2f 4c 20 34 36 34  |nearized 1/L 464|
00000030  34 34 2f 48 5b 20 34 33  39 36 38 20 31 34 32 5d  |44/H[ 43968 142]|
00000040  2f 4f 20 36 2f 45 20 34  33 39 36 38 2f 4e 20 31  |/O 6/E 43968/N 1|

[user1@pandora6 /tmp]$ hexdump -C /tmp/test_print.pdf | head -5
00000000  25 50 44 46 2d 31 2e 34  0a 25 c7 ec 8f a2 0a 34  |%PDF-1.4.%.....4|
00000010  20 30 20 6f 62 6a 0a 3c  3c 2f 4c 69 6e 65 61 72  | 0 obj.<</Linear|
00000020  69 7a 65 64 20 31 2f 4c  20 34 36 34 34 34 2f 48  |ized 1/L 46444/H|
00000030  5b 20 34 33 39 36 38 20  31 34 32 5d 2f 4f 20 36  |[ 43968 142]/O 6|
00000040  2f 45 20 34 33 39 36 38  2f 4e 20 31 2f 54 20 34  |/E 43968/N 1/T 4|
Run Code Online (Sandbox Code Playgroud)

Rik*_*Rik 9

嗯...十六进制00 00 B5 6C(你的额外字节反向)等于46444.所以我的猜测是TFileStream或SendStream在实际数据之前发送它想要发送的字节数.

查看Synapse的代码有以下功能:

procedure TBlockSocket.InternalSendStream(const Stream: TStream; WithSize, Indy: boolean);
Run Code Online (Sandbox Code Playgroud)

SendStream会像这样调用它:

  InternalSendStream(Stream, true, false);
Run Code Online (Sandbox Code Playgroud)

所以这WithSize是真的,并且流的大小在实际数据之前发送.

如果您使用SendStreamRaw,则发送时不会显示大小.

procedure TForm1.SpeedButton3Click(Sender: TObject);
var Client:TTCPBlockSocket;
    FS: TFileStream;
begin
  Client:=TTCPBlockSocket.Create;
  Client.RaiseExcept:=True;
  Client.Connect('192.168.1.95','9999');
  FS:=TFileStream.Create('/tmp/test_print.pdf',fmOpenRead);
  FS.Position:=0;
  Client.SendStreamRAW(FS);
  FS.Free;
  Client.CloseSocket;
  Client.Free;
end; 
Run Code Online (Sandbox Code Playgroud)