PDA

View Full Version : سوال: Connection Closed GraceFully



ali_reza_nazari
شنبه 07 مرداد 1391, 14:41 عصر
سلام
من نمونه کد زیر رو برای دانلود نوشتم
وقتی فایلهای متنی و پی دی اف رو دانلود می کنم. اصلا مشکلی نیست
به حجم هم حساسیت نداره
اما وقتی می خوام فایل فشرده یا اجرایی رو دانلود کنم به ارور


Connection Closed GraceFully
برخورد می کنم و ارتباط قطع میشه

اگه ممکنه راهنمایی بفرمایید





Procedure Download(var AContext: TIdContext);
Var
s: string;
TheStream : TFileStream;
Begin
with AContext.Connection Do
begin
IOHandler.Writeln('file name?');
s := IOHandler.ReadLn();
s := Base_Dir + s;
//Memo_server.Lines.Add('Execute : ' +s + DateTimeToStr(now()));
TheStream := TFileStream.Create(s, fmOpenRead);
IOHandler.Writeln(intToStr(TheStream.Size));
IOHandler.WriteBufferOpen;
IOHandler.WriteBufferClear;
IOHandler.Write(TheStream);
IOHandler.WriteBufferClose;
TheStream.Free;
//IOHandler.ReadBytes(
end;
End;

ali_reza_nazari
یک شنبه 08 مرداد 1391, 09:33 صبح
یعنی واقعا روش بهتری برای انتقال فایل وجود نداره؟
فقط همین روش هست؟
روش مطمئن تری برای انتقال فایلهای اجرایی نیست؟

BORHAN TEC
یک شنبه 08 مرداد 1391, 10:34 صبح
یادم میاد که قبلاً برای انتقال فایل ها مجبور شدم که به جای Indy از RemObjects SDK استفاده کنم که خوشبختانه چنین مشکلاتی را نداشت. اگر اشتباه نکنم در این مورد یک پروژه نمونه در کنارش وجود داره که میتونید از اون استفاده کنید.

ali_reza_nazari
یک شنبه 08 مرداد 1391, 11:16 صبح
متاسفانه تمامی مثالها براساس نگارش 9 نوشته شده اند و توی نسخه 10.5.7 من، فقط ارسال متن اونها کار می کنه و بقیه خطا میده
استفاده از کامپوننت های جانبی اگرچه کار رو راحت تر می کنند، اما امکان توسعه رو کمتر، چون اگر مثلا شما دلفی جدیدی نصب کنید باید کلی بگردید و کامپوننت به روز رو هم پیدا کنید. تازه اگه پیدا بشه. یک همچین مشکلاتی هست.
برای همین برای برنامه هایی که سریع تغییر می کنند باید سعی بشه تا اونجایی که ممکنه از کامپوننت های استاندارد استفاده بشه.
اگرچه شاید مجبور بشم کاری رو که گفتید رو انجام بدم.

gbg
یک شنبه 08 مرداد 1391, 13:04 عصر
خطایی در ارسال اتفاق میوفته و سرور ارتباط رو قطع میکنه

ali_reza_nazari
یک شنبه 08 مرداد 1391, 14:53 عصر
می دونم
این خطا در محتویات فایل اجرایی هست
یعنی یک سری اطلاعات باینری توی اون هست که برای سرور مفهوم داره و باعث اجرای یک سری دستورات مثل قطع کردن ارتباط میشه
سئوال من اینه که روش دیگه ای برای انتقال هست که این مشکل در اون بوجود نیاد و درواقع انتقال اطلاعات بوسیله اون روش گارانتی بشه؟

ali_reza_nazari
دوشنبه 09 مرداد 1391, 19:27 عصر
کسی از روش دیگه ای توی سرور و کلاینت ایندی برای انتقال فایل استفاده نکرده؟ همه از همین روش استفاده کردند؟ کسی چنین اروری ندیده؟

BORHAN TEC
دوشنبه 09 مرداد 1391, 20:31 عصر
کی گفته تمام مثالها بر اساس نسخه 9 است؟ در این صفحه مثالهای مربوط به Indy 10 وجود داره که می تونید از اونها استفاده کنید:
http://www.indyproject.org/Sockets/Demos/index.EN.aspx

برای اینکه نحوه انتقال فایلها رو بهتر متوجه بشید پیشنهاد می کنم که مثالهای IdFTP (FTP Client)و IdFTPServer را دانلود و مورد بررسی قرار بدید.

ali_reza_nazari
سه شنبه 10 مرداد 1391, 13:32 عصر
مگه برای اف تی پی نیاز نداریم که سرور اف تی پی داشته باشیم؟؟
وقتی آی پی ها ولید نیستند نمیشه از این سیستم استفاده کرد


تاریخ لینکی که دادید رو ببینید مربوط به 2004 تا 2005 هست.
ایندی دلفی ایکس ای 10.5.7 هست که توی خود ایندی پروجکت آخرین نسخه ای که بیرون اومده 10 هست و توی جاهای دیگه 10.4
یک لینک هم مربوط به آتوزد هست که خیلی وقته دیگه فعال نیست

BORHAN TEC
سه شنبه 10 مرداد 1391, 14:42 عصر
مگه برای اف تی پی نیاز نداریم که سرور اف تی پی داشته باشیم؟؟
برنامه ای که به عنوان سرور FTP می سازیم کار سرور رو انجام میده و به چیز بیشتری نیاز نیست.

وقتی آی پی ها ولید نیستند نمیشه از این سیستم استفاده کرد
میشه، من خودم شخصاً برنامه ای را برای این منظور ساخته ام و تست هم کرده ام که مربوط به یک شبکه محلی است.

تاریخ لینکی که دادید رو ببینید مربوط به 2004 تا 2005 هست.
Indy 10 هم مربوط به همان سالهاست ولی بنا به دلایلی و در صورت نیاز آپدیت شده است.

یک لینک هم مربوط به آتوزد هست که خیلی وقته دیگه فعال نیست
فعال است. Atozed در پروژه های مختلفی همکاری بسیار نزدیکی دارد.

ali_reza_nazari
جمعه 13 مرداد 1391, 12:44 عصر
Your OnExecute event handler has code in it that is not thread-safe (the Memo logic), and your Download() procedure is using write buffering when it should not be. Either of those could lead to unwanted exceptions being raised that will terminate the connection.

Try this code instead:



uses
..., IdSync;

type
TMemoNotify = class(TIdNotify)
protected
fMsg: String;
procedure DoNotify; override;
public
class procedure AddToMemo(const AMsg: String);
end;

class procedure TMemoNotify.AddToMemo(const AMsg: String);
begin
with Create do begin
fMsg := AMsg;
Notify;
end;
end;

procedure TMemoNotify.DoNotify;
begin
Form1.Memo_server.Lines.Add(fMsg);
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
Command : String;
begin
// FYI, if you switch to TIdCmdTCPServer, you can remove this OnExecute handler
// completely and use the TIdCmdTCPServer.CommandHandlers collection instead,
// which allow you to define per-command OnCommand handlers at design-time...

Command := AContext.Connection.IOHandler.ReadLn;
TMemoNotify.AddToMemo('Execute : ' + Command + #13 + DateTimeToStr(Now));

if TextIsSame(Command, 'download') then
Download(AContext)
else if TextIsSame(Command, 'list_of_file_dir') then
list_of_file_dir(AContext);
end;

procedure Download(AContext: TIdContext);
var
s: string;
TheStream : TFileStream;
begin
with AContext.Connection do
begin
IOHandler.WriteLn('file name?');

// warning: this is a potential security risk! Don't use the client's path
// as-is, you should sanitize it first before you then use it. Otherwise,
// a malicious client can pass in a filename that is preceeded with ".."
// and other folders to access files you do not want it to access...
s := Base_Dir + IOHandler.ReadLn;

TheStream := TFileStream.Create(s, fmOpenRead or fmShareDenyWrite);
try
IOHandler.WriteLn(IntToStr(TheStream.Size));
IOHandler.Write(TheStream);
finally
TheStream.Free;
end;
end;
end;


http://forums2.atozed.com/viewtopic.php?f=7&t=26228&sid=1681e78d0ddb240f489c9b2f88e8f44f