SQL сервер, например FireBird - это мн-о-о-о-о-гоплатформенное решение, единое, без сторонних зависимостей в виде денег, зависимости от платформы, зависимости от зависимостей

Модератор: Модераторы
stikriz писал(а):Почему бы не написать сервис/демон и посредством сокетов не передавать и обрабатывать как вздумается?
Brainenjii писал(а):через indy - никаких проблем не было
How do I send big chunks of data like files?
You can send big chunks by using the “ping-pong” principle. There are 2 events you need to understand first namely OnError and OnCanSend.
OnError is the most obvious one, it tells you that some error occured. It is important to watch this one when sending too because sends can fail with network errors (connection reset, timeout etc.).
OnCanSend is usually misunderstood. It’s the event which gets fired whenever you can send data AGAIN. This means that you first need to get to the state, when sending data is no longer possible (due to the OS buffer being full). This can be done by sending too much data too fast. How do you know it happened? If .Send or .SendMessage returns 0, and no OnError got called, you filled the OS send buffers and need to wait a bit. The OnCanSend event will tell you when you can continue sending.
So here’s how to best do sending. I’m using a “function GetNewChunk(): string” for imaginary function/method which returns a string of up to 65535 bytes (the usual max send size defined by OS). This function should either read from file or some other source you want to send from.
procedure TMyClass.OnCanSend(aSocket: TLSocket);
var
Sent: Integer; // number of bytes sent each try
TempBuffer: string = ''; // our local temp. buffer for the filestream, can be done smarter tho
begin
repeat
if Length(TempBuffer) = 0 then
TempBuffer := GetNewChunk; // get next chunk if we sent all from the last one
Sent := FConnection.SendMessage(TempBuffer, aSocket); // remember, don't use the aSocket directly!
Delete(TempBuffer, 1, Sent); // delete all we sent from our temporary buffer!
until (Sent = 0) or (AllIsSent); // try to send until you can't send anymore
end;
So basically, this handler will try to send in a loop until it can’t send anymore or there’s no more data to send. So how do you start sending then? I mean OnCanSend doesn’t get fired by lNet until you CAN’T send anymore.. well it’s simple. Just call the OnCanSend with the appropriate socket! But which socket you ask? Well if you’re a basic TCP client, then it’s simple, just the Iterator. If you’re a server, you need to know on which socket you want to send anyway.
But how come this sends the whole thing? What happens is this. You first call the OnCanSend handler yourself, ensuring that either everything is sent in one go, or that you sent so much that the OS buffer got filled up. If so then OnCanSend will get automagically called by lNet again when sending is possible. This way you end up with a kind of “ping-pong” style and all data gets sent when possible.
Тема: Re: LNet
Дата: Thu, 7 Jun 2012 09:46:26 +0200
От: Ales Katona
Кому: evgeny_veresk
aData is an untyped parameter. It's basically a pointer to anything (but you don't add @ before the variable).
For example if you have an array of byte like: myArray: array[0..100] of byte; you would send like:
lTCP.Send(myArray[1], length(myArray, aSocket);
Notice I used array[1] as the data argument because array[1] is where the real data starts and has 100 bytes length. Sending a record is more straightforward (you just do send(record, sizeof(record)));
Same goes for GET. You can get more info about this type of argument in the free pascal reference book.
Ales
Brainenjii писал(а):Закачка файла с клиента на сервер работает без нареканий, при загрузке с сервера на клиент последний буфер ЗАРАЗА ТАКАЯ УХОДИТЬ НЕ ХОЧЕТ НИ В КАКУЮ!!!!!11111разраз
Brainenjii писал(а):но всю жизнь считал свой код самодостаточным по информативности ^_^
function TForm1.SendFile (filename: string; remote_ip: string; remote_port: word): boolean;
var
binfile: file;
i: int64;
buf: byte;
TCP: TLTCPComponent;
begin
TCP.Create(Form1);
TCP.Port:=remote_port;
TCP.Host:=remote_ip;
AssignFile (binfile, UTF8ToSys(filename));
Reset(binfile,1);
For i:=1 to FileSize(UTF8ToSys(filename)) do
begin
BlockRead(binfile,buf,1);
TCP.Send(buf, 1);
end;
label2.Caption:=label2.Caption+ ' ' + IntTostr(i);
CloseFile(binfile);
end;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 229