ارتباط با Indy Server در اینترنت
با سلام خدمت دوستان
من یک نرم افزار کلاینت سروری با indy نوشتم که نسخه سروری اون روی سروری نصب شده که روش IP Valid ست شده . حال مشکل کار اینجاست وقتیکه از نسخه کلایت وصل میشم بهش هیچ مشکلی ندارم و کانکت میگیرم ولی وقتی نرم افزار نسخه سرور چیزی رو میخواد برگردونه (به اصلاح write انجام بده) برای نسخه کلاینت از اونجا که پکت ها در اصل بر میگیردن به آدرس NAT شبکه که همون آدرس ISP سمت کلاینت ها هستش همه پکت ها از بین میرن و به نرم افزار کلاینت نمیرسه.
راه حلی برای این موضوع هست؟؟
نقل قول: ارتباط با Indy Server در اینترنت
ایا روی همون کانکشنی که TCPClient باز کرده اطلاعات رو بر میگردونید؟
نقل قول: ارتباط با Indy Server در اینترنت
آره رو همون بر میگردونم ولی آدرس چون Nat میشه به کلاینت نمیرسه و فکر میکنم پکت لاست میشه
نقل قول: ارتباط با Indy Server در اینترنت
نه عزیزجان. همچین فکری نکن.
مشکل جای دیگست.
چون شما داری رو همون کانکشن دیتا رو بر میگردونی. ربطی به ای پی و پورت نداره.
نقل قول: ارتباط با Indy Server در اینترنت
ممنون از پاسختون جناب ماسک ولی به نظر شما مشکل کجا میتونه باشه؟؟؟؟
من آی پی کانکشن کلاینتی رو که میبینم روی سرور یک آی پی ولیده که اونم مال ISP
نقل قول: ارتباط با Indy Server در اینترنت
نمونه ای از دستورات ارسال کلاینت و پاسخ سرور رو قرار بدید
نقل قول: ارتباط با Indy Server در اینترنت
ممنون از توجهتون جناب Mahmood_M
من نسخه سرور رو با دلفیXE7 نوشتم و نسخه کلاینتم رو با کیوت نوشتم که نسخه سروم یکسری کدش به صورت زیره :
procedure TForm1.FormCreate(Sender: TObject);
begin
IdTCPServer1.Bindings.Clear;
IdTCPServer1.Bindings.Add.SetBinding('آدرس آی پی ولید سرور', 9091);
IdTCPServer1.Active := True;
end;
procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
ListBox1.Items.Add ('Connected from: ' +
AContext.Connection.Socket.Binding.PeerIP+'*** Date :'+PrintNormal);
end;
procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
begin
ListBox1.Items.Add ('Disconnect from: ' +
AContext.Connection.Socket.Binding.PeerIP);
ListBox1.Items.Add('-----------------------------');
end;
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
MyID : string;
begin
with AContext.Connection do
try
MyID:= AContext.Connection.Socket.ReadLn;
ListBox1.Items.Add ('MyID is : ' + MyID);
DM.qr_ValidID.Close;
DM.qr_ValidID.Params[0].Value := MyID;
DM.qr_ValidID.Open;
if DM.qr_ValidID.IsEmpty then
Socket.WriteLn('Your ID Not Valid')
ELSE
{ Other My Statement}
except
on e: Exception do
begin
WriteLn('Error: ' + e.Message);
end;
end; //on
AContext.Connection.Disconnect;
end;
نسخه کلاینت رو هم ه با C++ نوشتم تقریبا به همین شکله. الان هم هر دوتا نرم افزار وقتی تو یک شبکه lan استفاده میکنم کار میکنن ولی وقتی نسخه سرور رو روی سروری که اینترنت و آی پی ولید داره نصب میکنم از یک سیستمی که کانکت میشم ارتباط برقرار میشه ولی پاسخ از سمت سرور به کلاینت ارسال نمیشه
نقل قول: ارتباط با Indy Server در اینترنت
چند تا مشکل وجود داره
اول اینکه متد Execute مربوط به IdTCPServer در یک Thread جداگانه اجرا میشه و شما نمی تونید از داخل یک Thread دیگه به عناصر روی فرم مثل ListBox1 دسترسی داشته باشید
دوم اینکه از داخل یک Thread نباید از Connection های Thread اصلی ( مثلا در DataModule ) استفاده کنید، هر Thread باید Connection مخصوص خودش رو داشته باشه
برای تغییر ListBox از Synchronize استفاده کنید
برای گرفتن Query ، ابتدا یک Connection و Query در همین متد Create کنید و بعد اتصال رو انجام بدید، از Connection های روی فرم استفاده نکنید
اگر در ابتدای کد BreakPoint بزارید احتمالا می بینید که قبل از رسیدن به WriteLn برنامه متوقف میشه
* برای WriteLn بهتره به جای Socket از IOHandler استفاده کنید :
AContext.Connection.IOHandler.WriteLn()
نقل قول: ارتباط با Indy Server در اینترنت
ممنون از کمکتون
ولی این برنامه داره کار میکنه و اجرا میشه
نمونه کدش رو هم از چند تا سایت که در رابطه ارتباط با بانک اطلاعاتی بود و با indy طراحی کرده بودن گذاشتم و استفاده کردم ازشون. اگه نمونه کد مشابه که بشه ازش استفاده کردید بذارید برام ممنون میشم.
نقل قول: ارتباط با Indy Server در اینترنت
همون مواردی که گفته شد رو لحاظ کنید کفایت می کنه
و اینکه به جای Socket از IOHandler استفاده کنید ( پست قبل رو ویرایش کردم )
نقل قول: ارتباط با Indy Server در اینترنت
یک مثال ساده :
procedure TMainFrm.IdTCPServer1Execute(AContext: TIdContext);
var
MyID : String;
Q : TQuery;
begin
MyID:= AContext.Connection.IOHandler.ReadLn();
Synchronize(
Procedure
Begin
ListBox1.Items.Add('MyID is : ' + MyID);
end );
Q := TQuery.Create(nil);
Q.ConnectionString := 'MyConnectionString';
Q.SQL.Text := '';
try
try
Q.Active := True;
if Q.RecordCount > 0 then
Msg := 'Successfull !';
else
Msg := 'Error !';
except
on E:Exception do
begin
Msg := 'Error on Query !';
end;
end;
finally
AContext.Connection.IOHandler.WriteLn(Msg);
Q.Active := False;
Q.Free;
end;
به Synchronize و استفاده از Query توجه کنید، رعایت نکردن این موارد در کار با Thread ها مشکلات زیادی رو براتون ایجاد می کنه
نقل قول: ارتباط با Indy Server در اینترنت
ممنون از مثالتون دوست من
ولی بازم مشکلم در رابطه با برگشت پاسخ به کلاینت مشکلم حل نشد:گریه::گریه:
شما به همچین مشکلاتی برخورد نکردید تا حال یا دوستان دیگه؟؟؟؟؟؟؟؟؟؟
نقل قول: ارتباط با Indy Server در اینترنت
لطفا یک نمونه پروژه ( هم کلاینت و هم سرور ) قرار بدید تا بررسی بشه
نقل قول: ارتباط با Indy Server در اینترنت
ممنون از توجهتون دوست من
مشکل رو پیدا کردم از کجا بود
رو سرور یک *** Server شده بود بخاطر همین همه پورت های اضافی بسته شده بود. واسه همین وقتی نمیشه دیتا ارسال کرد
وقتی هر دو تا برنامه رو دلفی نوشتم و هر دوتاشون رو رو سرور اجرا کردم اونجا هم جواب نمیداد
ولی وقتی فقط نسخه کلاینت رو روی سرور نصب کردم و نسخه سرور رو هم روی یکی از کلاینت ها نصب کردم که تو شبکه Lan بود مشکل حل شد
در کل تجربه خوبی بود
فقط میشه لطف کنید یکسری اطلاعاتی مفید در رابطه با indy و نوشتن وب سرور با indy اگه دارید بذارید برام ؟؟
با تشکر از هم :بوس: