comprimere una stringa base64 sembra che non dia risultati eccezionali
ho fatto un po' di calcoli sulle stringhe inviate
dopo Len1 c'è la lunghezza dei dati da inviare (quindi dovrebbe essere la lunghezza B64)
dopo Len2 c'è la lunghezza dopo la compressione
come vedi quando la stringa è piccola (32 byte), addirittura non conviene comprimere (diventano 43 byte)
quando la stringa B64 è più grande, a volte conviene, a volte no
se non ho fatto errori, alla fine, dopo 100 invii la compressione ha ridotto i dati del 9.11%
sotto ci sono i miei calcoli
se vuoi ti mando le modifiche con cui ho fatto questi conteggi così che puoi verificare anche tu
Nr. 1 - Len1 32- Len2 43
Nr. 2 - Len1 32- Len2 43
Nr. 3 - Len1 32- Len2 43
Nr. 4 - Len1 32- Len2 43
Nr. 5 - Len1 16- Len2 24
Nr. 6 - Len1 16- Len2 24
Nr. 7 - Len1 16- Len2 24
Nr. 8 - Len1 16- Len2 24
Nr. 9 - Len1 16- Len2 24
Nr. 10 - Len1 16- Len2 24
Nr. 11 - Len1 16- Len2 24
Nr. 12 - Len1 16- Len2 24
Nr. 13 - Len1 856- Len2 844
Nr. 14 - Len1 856- Len2 844
Nr. 15 - Len1 856- Len2 844
Nr. 16 - Len1 856- Len2 844
Nr. 17 - Len1 16- Len2 24
Nr. 18 - Len1 16- Len2 24
Nr. 19 - Len1 8016- Len2 7599
Nr. 20 - Len1 8016- Len2 7996
Nr. 21 - Len1 8016- Len2 5317
Nr. 22 - Len1 8016- Len2 6930
Nr. 23 - Len1 8016- Len2 3259
Nr. 24 - Len1 8016- Len2 8027
Nr. 25 - Len1 1104- Len2 1115
Nr. 26 - Len1 16- Len2 24
Nr. 27 - Len1 16- Len2 24
Nr. 28 - Len1 8016- Len2 7190
Nr. 29 - Len1 8016- Len2 6128
Nr. 30 - Len1 8016- Len2 4553
Nr. 31 - Len1 8016- Len2 6085
Nr. 32 - Len1 3664- Len2 3675
Nr. 33 - Len1 16- Len2 24
Nr. 34 - Len1 16- Len2 24
Nr. 35 - Len1 8016- Len2 7995
Nr. 36 - Len1 8016- Len2 8027
Nr. 37 - Len1 8016- Len2 7290
Nr. 38 - Len1 8016- Len2 5972
Nr. 39 - Len1 8016- Len2 7485
Nr. 40 - Len1 8016- Len2 8008
Nr. 41 - Len1 8016- Len2 7936
Nr. 42 - Len1 8016- Len2 7900
Nr. 43 - Len1 8016- Len2 7812
Nr. 44 - Len1 8016- Len2 7818
Nr. 45 - Len1 8016- Len2 7764
Nr. 46 - Len1 8016- Len2 7763
Nr. 47 - Len1 584- Len2 595
Nr. 48 - Len1 16- Len2 24
Nr. 49 - Len1 16- Len2 24
Nr. 50 - Len1 8016- Len2 7954
Nr. 51 - Len1 8016- Len2 8027
Nr. 52 - Len1 8016- Len2 7851
Nr. 53 - Len1 8016- Len2 7832
Nr. 54 - Len1 8016- Len2 7888
Nr. 55 - Len1 8016- Len2 8027
Nr. 56 - Len1 8016- Len2 7094
Nr. 57 - Len1 8016- Len2 7958
Nr. 58 - Len1 8016- Len2 7974
Nr. 59 - Len1 8016- Len2 7750
Nr. 60 - Len1 8016- Len2 7126
Nr. 61 - Len1 8016- Len2 7750
Nr. 62 - Len1 8016- Len2 8027
Nr. 63 - Len1 8016- Len2 8027
Nr. 64 - Len1 8016- Len2 7813
Nr. 65 - Len1 5608- Len2 5277
Nr. 66 - Len1 16- Len2 24
Nr. 67 - Len1 16- Len2 25
Nr. 68 - Len1 8016- Len2 7465
Nr. 69 - Len1 8016- Len2 7547
Nr. 70 - Len1 8016- Len2 6396
Nr. 71 - Len1 8016- Len2 7495
Nr. 72 - Len1 8016- Len2 7520
Nr. 73 - Len1 8016- Len2 7518
Nr. 74 - Len1 8016- Len2 7524
Nr. 75 - Len1 8016- Len2 7505
Nr. 76 - Len1 8016- Len2 7523
Nr. 77 - Len1 8016- Len2 7153
Nr. 78 - Len1 6520- Len2 6531
Nr. 79 - Len1 16- Len2 24
Nr. 80 - Len1 16- Len2 25
Nr. 81 - Len1 8016- Len2 6571
Nr. 82 - Len1 8016- Len2 5114
Nr. 83 - Len1 8016- Len2 4607
Nr. 84 - Len1 8016- Len2 6976
Nr. 85 - Len1 392- Len2 403
Nr. 86 - Len1 16- Len2 24
Nr. 87 - Len1 16- Len2 25
Nr. 88 - Len1 8016- Len2 8002
Nr. 89 - Len1 8016- Len2 8027
Nr. 90 - Len1 8016- Len2 7251
Nr. 91 - Len1 8016- Len2 5430
Nr. 92 - Len1 8016- Len2 7252
Nr. 93 - Len1 8016- Len2 7997
Nr. 94 - Len1 8016- Len2 7874
Nr. 95 - Len1 8016- Len2 7821
Nr. 96 - Len1 8016- Len2 7664
Nr. 97 - Len1 8016- Len2 7772
Nr. 98 - Len1 8016- Len2 7101
Nr. 99 - Len1 6904- Len2 6609
Nr. 100 - Len1 16- Len2 24
Tot Send = 100 - base64 bytes = 525688 - sended bytes = 479365 - ratio = 9.1188119188568129E-001
Edit:
forse bisognerebbe comprimere +crittare prima e convertire in B64 poi
però il JPEG in effetti è già compresso
forse sto prendendo un abbaglio ma tu spedisci con SendStream che accetta un parametro di tipo TStream
per me va già bene
unit blcksock;
...
{:Send content of stream to socket. It using @link(SendBlock) method}
procedure SendStream(const Stream: TStream); virtual;
...
secondo me il problema non è synapse
qualcosa del genere potrebbe andare
è una classe che splitta un maxi-pacchetto in tanti pacchetti di una dimensione minore
poi l'invio dovrebbe inviarli tutti
come la vedete?
const
MAXSIZEPACKET = 4096;
type
TPacketData = array [1..MAXSIZEPACKET] of char;
TSplittedPacket = record
ID: Int64; // identifica un unico pacchetto
PacketNo, // numero dello split corrente
TotPackets: Int64; // totale split
Size: Int64; // dimensioni dati in Data (per ultimo pacchetto)
Data: TPacketData;
end;
TSplittedPackets = array of TSplittedPacket;
class TSplitedPacket ....
PacketList: TSplittedPacket;
private
procedure DoSplitPacket(AStream: TStream);
public
procedure LoadPacket(AStream: TStream);
end;
procedure TSplitedPacket.LoadPacket(AStream: TStream);
var need: Int64;
begin
SetLength(PacketList, (Astream.Size div MAXSIZEPACKET) + 1);
DoSplitPacket(AStream);
end;
procedure TSplitedPacket.DoSplitPacket(AStream: TStream);
var scan: Int64;
SplittedBytes: Int64;
begin
SplittedBytes:=0;
for scan := 0 to length(PacketList) - 1 do begin
PacketList.ID = "numero invio";
PacketList.PacketNo := scan;
PacketList.TotPackets := length(PacketList);
PacketList.Data := ...
end;
end
Edit:
ho corretto il codice che presentava qualche errore
Edit2:
l'invio dovrebbe inviare una struttura TSplittedPacket (serializzata in qualche modo)
così da poter ricostruire il pacchetto originale usando PacketNo e TotPackets
ma la scansione a scacchi, credo, vada implementata
Si, sono d'accordo. Deve essere una opzione per l'ottimizzazione.
Con riferimento a ciò, prima di implementare qualsiasi cosa pensiamo alla struttura di trasmissione.
Lavorare a scacchi lo credevo anche io, ma alla fine sull'udp non sono così sicuro che incida, sono da fare delle prove quando abbiamo l'infrastruttura di rete su cui trasmettere i dati. Fosse su TCP concordavo con te.
Io comunque posso mettere in piedi un semplice repeater nel server Internet con 4 porte fisse (per adesso, in attesa di implementare la dinamicità) per simulare un assistito e un assistente.
Una porta UDP e una TCP in ascolto (chiamiamole impropriamente server) e una porta UDP e TCP in ascolto (client) per la ritrasmissione dello stesso dato ricevuto allo stesso IP di ricezione (per adesso). Gli IP connessi (SERVER) verranno confrontati a quelli connessi (CLIENT) e i dati verranno reindirizzati se gli IP collimano. Per adesso implemento solo protocollo IPV4 e ovviamente i dati andranno sia da client e server sia da server a client.
La coda di listen sarà di 10 connessioni contemporanee massime per porta.
Internet a 1 Gigabit, MTU su Internet di 1500 byte (1448 byte dati), ma non è detto che l'MTU sia anche il vostro. Se volete provare la frammentazione, dovete eseguire un ping verso l'indirizzo interessato con le opzioni -f -l
ping 217.198.132.230 -f -l 1448
Se vi genera un messaggio di avvertimento allora provate a diminuire il valore 1448.
Ciao
P.S.: appena pronto vi invio in chat privata le porte da usare.
Occhio nel fare il timing del codice: il GetTickCount64 è assolutamente impreciso; non l'ho mai usato, ho sempre usato la routine diagnostica che ho postato anche in questo forum o una routine assembler pura.
Riporto dal link di Microsoft: https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount64 (https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount64)
La risoluzione della funzione GetTickCount64 è limitata alla risoluzione del timer di sistema, che in genere è compresa tra 10 millisecondi e 16 millisecondi. La risoluzione della funzione GetTickCount64 non è influenzata dalle modifiche apportate dalla funzione GetSystemTimeAdjustment.
Infatti le analisi che stavo eseguendo non avevano senso misurate con questo "cronometro".
Io normalmente uso questo (c'è anche la funzione di calibrazione delle costanti CiclialMs e Ciclialus ... ma la posterò in un topic più consono):
//per Cicli: costante di cicli al millisecondo nelle CPU di nuova generazione (dalle serie Intel 8 in poi ?)
const CiclialMs = 2000000; //Mezzo nanosecondo a ciclo
//per Cicli: costante di cicli al microsecondo nelle CPU di nuova generazione (dalle serie Intel 8 in poi ?)
const Ciclialus = 2000; //Mezzo nanosecondo a ciclo
function Cicli: UInt64; register;
begin
{$IFDEF WIN64}
asm
//Per i processori INTEL, il conteggio ritornato da rdtsc è invariante (no clock / no core), dipende dalla CPU ed è di circa mezzo nanosecondo
rdtsc; //(RDX:RAX in 64 bit)
lfence;
shl RDX, 32
or RAX, RDX //RAX per i valori di ritorno come intero sino a 64 bit (in WIN64)
end;
{$ENDIF}
end;
//Uso:
var t1, t2: UInt64;
//In t1 vengono riportati i cicli attuali del processore
t1 := Cicli;
//..... fai qualcosa
t2 := Cicli;
//Millisecondi trascorsi
ShowMessage('diff = ' + IntToStr((t2-t1) div CiclialMs));
//Microsecondi trascorsi
ShowMessage('diff = ' + IntToStr((t2-t1) div Ciclialus));
Ciao
è probabile che questo si a un problema relativo a Windows
se non ho capito male nei sistemi *nix/posix si usa clock_settime (CLOCK_MONOTONIC) che pare avere una accuratezza in nanosecondi
detto questo ho guardato nei sorgenti di lazarus e GetTickCount64 è un wrapper a seconda dell'OS
sorgenti linux
function GetTickCount64: QWord;
var
tp: TTimeVal;
{$IFDEF HAVECLOCKGETTIME}
ts: TTimeSpec;
{$ENDIF}
begin
{$IFDEF HAVECLOCKGETTIME}
if clock_gettime(CLOCK_MONOTONIC, @ts)=0 then
begin
Result := (Int64(ts.tv_sec) * 1000) + (ts.tv_nsec div 1000000);
exit;
end;
{$ENDIF}
fpgettimeofday(@tp, nil);
Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_usec div 1000);
end;
sorgenti windows
function GetTickCount64: QWord;
{$IFNDEF WINCE}
var
lib: THandle;
{$ENDIF}
begin
{$IFNDEF WINCE}
{ on Vista and newer there is a GetTickCount64 implementation }
if Win32MajorVersion >= 6 then begin
if not Assigned(WinGetTickCount64) then begin
lib := LoadLibrary('kernel32.dll');
WinGetTickCount64 := TGetTickCount64(
GetProcAddress(lib, 'GetTickCount64'));
end;
Result := WinGetTickCount64();
end else
{$ENDIF}
Result := Windows.GetTickCount;
end;
sotto linux il tempo di confronto che avevo ottenuto era di 5ms e mi sembrava congruo
sotto win che tempi di risposta si ottengono?