Delphi Can

Orjinalini görmek için tıklayınız: VCL Local IP Değiştirme
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Sayfalar: 1 2
Merhaba arkadaşlar.

Local IP'yi değiştirmek istiyorum. Biraz araştırma yaptım fakat stabil çalışan bi örnek bulamadım. Var mı sizlerde stabil çalışan bir örnek?
(06-08-2024, Saat: 23:16)mcuyan Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba arkadaşlar.

Local IP'yi değiştirmek istiyorum. Biraz araştırma yaptım fakat stabil çalışan bi örnek bulamadım. Var mı sizlerde stabil çalışan bir örnek?

Merhabalar,

Örnek mevcut. İncelemek isteyebilirsiniz.

https://stackoverflow.com/questions/12574843/how-to-set-my-ip-address-programmatically


Kolay gelsin.
Merhaba

Belli bir Network kartı ve sadece network kartına ilişkin IP profil ayarı için çözümler bulunur.

Değiştirilmek için verilmek istenen IP'nin ağ üzerinde var olup olmadığı öncelikle kontrol edilmelidir. Yoksa çakışma nedeniyle ağ bağlantısı sağlanamaz. Belki de mevcut çözümlerdeki yaşadığınız stabil olmama durumu bundan kaynaklıdır.

İlave olarak bazı senaryoları da kurmak lazım gerekiyor olabilir.

Local IP yerine göre 1 yerine göre birden fazla sayıda olabilir. VPN veya birden fazla network kartı vb. bir wifi + 1 lan bağlantısı buna örnektir.

Sizin hangisiyle ilgilenip onun LAN IP'sini değiştireceğiniz kullanıcı davranışına bağlıysa işiniz zor.

Buna örnek olarak kullanıcı bazlı wifi kapat LAN kablosuna geç, onu kapat bluetooth network kullan hatta usb network paylaşım sınan telefonla ağa bağlan gibi durumlar hesaba katılmalı.

Bunlar sadece senaryo. Kolay gelsin
Şöyle anlatayım;

Server da (Bu normal bi pc), FB database e bağlanmak içn diğer clientler'ı sabit bi ip ye yönlendiriyorum. PC Adı ile de denemelerim oldu fakat bazen pc adına adresleyemediği için stabil bir çalışma bulamadım.
Mesela ISS servis sağlayıcı kökenli bi problem olduğunda kullanıcı sorun gidere basıyor ve ana makina IP adresi değişiyor. Ben bu IP adresi alt ağ maskesi ve dhcp dns sunucu ip adr. datasını db de saklayıp bu tür bi problem de tekrardan eski haline getirmek istpyurm. Fakat stabil çalışan bi örnek bulamadım.

@hi_selamlar hocam o örneği denedim ama  IO error 105 alıyorum. anlamadım.

Şurada bi örnek buldum. Uygulama hata vermeden çalışıyor ama eylem yok.

https://theroadtodelphi.com/2011/10/30/w...etworking/


function ArrayToVarArray(Arr : Array Of string):OleVariant; overload;
var
i : integer;
begin
   Result   :=VarArrayCreate([0, High(Arr)], varVariant);
   for i:=Low(Arr) to High(Arr) do
    Result[i]:=Arr[i];
end;

function ArrayToVarArray(Arr : Array Of Word):OleVariant;overload;
var
i : integer;
begin
   Result   :=VarArrayCreate([0, High(Arr)], varVariant);
   for i:=Low(Arr) to High(Arr) do
    Result[i]:=Arr[i];
end;

procedure  SetStaticIP;
const
 wbemFlagForwardOnly = $00000020;
var
 FSWbemLocator : OLEVariant;
 FWMIService   : OLEVariant;
 FWbemObjectSet: OLEVariant;
 FWbemObject   : OLEVariant;
 oEnum         : IEnumvariant;
 iValue        : LongWord;
 vIPAddress         : OleVariant;
 vSubnetMask        : OleVariant;
 vDefaultIPGateway  : OleVariant;
 vGatewayCostMetric : OleVariant;
begin
 FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
 FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
 FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapterConfiguration Where IPEnabled=True','WQL',wbemFlagForwardOnly);
 oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
 while oEnum.Next(1, FWbemObject, iValue) = 0 do
 begin
   vIPAddress   := ArrayToVarArray(['192.168.1.141']);
   vSubnetMask  := ArrayToVarArray(['255.255.255.0']);
   if FWbemObject.EnableStatic(vIPAddress, vSubnetMask) = 0 then
   begin
     vDefaultIPGateway  := ArrayToVarArray(['192.168.1.100']);
     vGatewayCostMetric := ArrayToVarArray([1]);
     FWbemObject.SetGateways(vDefaultIPGateway,vGatewayCostMetric);
   end;

   VarClear(vIPAddress);
   VarClear(vSubnetMask);
   VarClear(vDefaultIPGateway);
   VarClear(vGatewayCostMetric);
   FWbemObject:=Unassigned;
 end;
end;
Problemi doğru anladıysam FB db nin bulunduğu pcnin IP sini localde otomatik bulacak bir öneride bulunayım.
İşlem adımları:
  • DB sunucuya broadcast mesajları dinleyen ve cevap veren bir yapı kurun.
  • Client pcler dbye bağlanamadığı durumda, "Sunucuyu Bul" gibi bir uyarı çıkartın.
  • Client pc de butona basınca, local ağa "Sunucu nerdesin Smile" gibi broadcast mesajı gönderin.
  • Mesajı alan db sunucu, bu mesaja "Benim IP 192.x.x.x" şeklinde cevap versin.
  • Client pc sunucudan gelen udp cevabı dinlesin ve cevabı alsın.
  • Client pc tarafında db bağlantı için bu IP yi kullanın.
Buradaki tüm işlemleri Indy udpserver ve udpclient komponentleri ile yapabilirsiniz.

Client pc lerdeki yazılıma bu yapıyı eklersiniz.
Sunucu tarafında çalışan bir uygulamanız yoksa, broadcast dinleyecek ve cevap verecek bir uygulama veya servis yazmanız gerekir.

Yaşayabileceğiniz muhtemel problem ve çözüm önerisi:

Güncel windows işletim sistemlerinde broadcast mesajını 255.255.255.255 şeklinde göndermenize izin vermiyor.
Birden fazla ethernet kartı varsa (fiziksel veya sanal ethernet kartları) gatewayin bağlı olduğu ethernet kartını tespit etmeniz gerekmektedir.

Daha sonra bu ethernet kartının gateway IP sini veya bilgisayarın aldığı local IP yi ardından da ağ maskesini öğrenmeniz gerekmekte.

Örneğin: 
Gateway 192.168.1.1
Local IP: 192.168.1.68
NetMask . 255.255.255.0

Bu değerlerden aşağıdaki formatta broadcast IP si oluşturulmalı

Broadcast Ipsi : 192.168.1.255

Bu sayede pclerin IP lerini değiştirmeye gerek kalmadan, sadece uygulamanın db bağlantı ayarını değiştirerek çözüm bulabilirsiniz.
Client pc sunucudan gelen udp cevabı dinlesin ve cevabı alsın.
Client pc tarafında db bağlantı için bu IP yi kullanın.

@frmman arkadaşın verdiği yöntem en sağlıklı yöntemdir, işin içine mac adresini de katarsak , örneğin gerekli olacak pc nin mac adresini db de saklayıp ağ üzerinde broadcast edilen mesajda mac adresi de yayınlanırsa, gelen mesaj db deki mac adresiyle eşitse yazılım da "hmm yeni ıp adresi buymuş , demekki bu adres ile haberleşmeliyim" demeli.

Türkiyenin çok ünlü bir yazılım firması olan (markayı sansürleyeyim)  (A***Soft) un cafe programı, ana makine veya clientler açılır açılmaz  local ağ üzerinde udp broadcast mesajı yolluyor, ana makine, gelen broadcast mesajlarını anında parse ederek sabit mac adreslerine göre modemin verdiği değişken ıp lerin hangi makine olduğunu güncelleyip veritabanında ıp yi güncelliyor.

Bir fikir vermesi açısından arşivimde bulduğum bir kod, udp server clientlerin mesaj göndermesine örnek.
ilginçtir ki, bu örnekte IP ile pek işi yok gibi. Var aslında da, bu örnekte udp sinyalini gönderdiğimizde, önceden belirlediğimiz portların dinlemesine açık olmalı.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Sockets, StdCtrls, IdBaseComponent, IdComponent, IdUDPBase,
 IdUDPClient, IdUDPServer,  IdSocketHandle;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Edit1: TEdit;
   Memo1: TMemo;
   Memo2: TMemo;
   UDPClient1: TIdUDPClient;
   UdpSocket1: TUdpSocket;
   IdUDPServer1: TIdUDPServer;
   procedure Button1Click(Sender: TObject);
   procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
   ABinding: TIdSocketHandle);
   procedure UdpSocket1Receive(Sender: TObject; Buf: PAnsiChar;
     var DataLen: Integer);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
udpclient1.Send('Test');
UdpSocket1.Sendln(edit1.Text,'#+D#+A');
memo1.Lines.Add(edit1.Text);
edit1.Clear;
end;

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
 ABinding: TIdSocketHandle);
var
 DataStringStream: TStringStream;
 Msg: String;
begin
 DataStringStream := TStringStream.Create('');
 try
   DataStringStream.CopyFrom(AData, AData.Size);
   Msg := DataStringStream.DataString;
 finally
   DataStringStream.Free;
 end;
memo2.Lines.Add(Msg);

end;

procedure TForm1.UdpSocket1Receive(Sender: TObject; Buf: PAnsiChar;
 var DataLen: Integer);
var
 DataStringStream: TStringStream;
 Msg: String;
begin
 DataStringStream := TStringStream.Create('');
 try
//    DataStringStream.CopyFrom(AData, AData.Size);
   Msg := DataStringStream.DataString;
 finally
   DataStringStream.Free;
 end;
memo2.Lines.Add(Msg);

end;

end.

object Form1: TForm1
  Left = 192
 Top = 124
 Width = 662
 Height = 379
 Caption = 'Form1'
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = 'MS Sans Serif'
 Font.Style = []
 OldCreateOrder = False
 PixelsPerInch = 96
 TextHeight = 13
 object Button1: TButton
   Left = 432
   Top = 16
   Width = 75
   Height = 25
   Caption = 'Button1'
   TabOrder = 0
   OnClick = Button1Click
 end
 object Edit1: TEdit
   Left = 24
   Top = 24
   Width = 337
   Height = 21
   TabOrder = 1
 end
 object Memo1: TMemo
   Left = 16
   Top = 72
   Width = 593
   Height = 113
   Lines.Strings = (
     'Memo1')
   ScrollBars = ssVertical
   TabOrder = 2
 end
 object Memo2: TMemo
   Left = 16
   Top = 216
   Width = 601
   Height = 113
   Lines.Strings = (
     'Memo2')
   ScrollBars = ssVertical
   TabOrder = 3
 end
 object UDPClient1: TIdUDPClient
   Active = True
   Port = 8090
   Left = 368
   Top = 24
 end
 object IdUDPServer1: TIdUDPServer
   Active = True
   Bindings = <>
   DefaultPort = 8090
   OnUDPRead = IdUDPServer1UDPRead
   Left = 376
   Top = 176
 end
 object UdpSocket1: TUdpSocket
   Active = True
   OnReceive = UdpSocket1Receive
   Left = 248
   Top = 48
 end
end
Hocam yorum ve örnekleriniz muazzam derece de güzel ve açıklayıcı.

Fakat maalesefki remote bağlantı modemden port açılımı vs işleri için Ana Pc nin ip si sabit ve o ip nin modeme port ile birlikte route edilmesi gerekmekte.

Kısacası sabit ip yi tanımlamam gerekiyor ana pc ye.
Sormaya çekiniyorum ama projeniz "AsAdmin" olarak çalışıyor değil mi?  
Ayrıca daha önce denediğinizi bildirdiğiniz kodların ilgili IP değişim yapacak IF bloğuna girip girmediğini içeride showmessage vb kontrol etme imkanınız oldu mu ?

Sizin için aşağıdaki şekilde bir örnek hazırladım. Burada en azından sorunun ne olduğunu anlamanız konusunda faydalı olacaktır.
 
Yaptığı iş, sırayla IP aktif network kartlarını dolaşıp seçtiğiniz birinin IP adresini değiştirmek. Eğer bu işlemi yapabiliyorsa bu kodu revize ederek dilediğiniz forma sokabilirsiniz. Kontrolleri de içinde bıraktım.

örneğin : 



Uses WinSock, ComObj, ActiveX;

procedure ChangeIp(
    aIp         : string = '192.168.0.26';
    aSubNetMask : string = '255.255.255.0';
    aDefGateway : string = '192.168.0.1'    );
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator       : OLEVariant;
  FWMIService         : OLEVariant;
  FWbemObjectSet      : OLEVariant;
  FWbemObject         : OLEVariant;
  oEnum               : IEnumvariant;
  iValue              : LongWord;
  vIPAddress          : OleVariant;
  vSubnetMask         : OleVariant;
  vDefaultIPGateway   : OleVariant;
  vGatewayCostMetric  : OleVariant;
  LLo, LMax, i        : Integer;
  LExit : Boolean;
  FOutParams          : Integer;
begin
  FSWbemLocator  := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService    := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapterConfiguration'
    +' where IPEnabled=True','WQL', wbemFlagForwardOnly);
  oEnum          := IUnknown( FWbemObjectSet._NewEnum) as IEnumVariant;

  LExit := false;
  while  (NOT LExit) and (oEnum.Next(1,  FWbemObject,  iValue) = 0) do
  begin
    if not VarIsClear(FWbemObject.IPAddress) then
    begin
      LLo  :=  VarArrayLowBound  ( FWbemObject.IPAddress, 1  );
      LMax :=  VarArrayHighBound ( FWbemObject.IPAddress, 1  );
      i := LLo;
      while (NOT LExit) and (i <= LMax) do
      begin
        if pos( ':', String(FWbemObject.IPAddress[i]) ) = 0
        then
          if MessageDlg( Format('Bunu mu Değiştirelim : ' + sLineBreak
           + 'IP: %s Desc: %s',[
             String(FWbemObject.IPAddress[i])
            ,String(FWbemObject.Description)
            ]), mtConfirmation, [mbYes, mbNo], 0 ) = mrYes then
            begin
              // Değişim Vakti
              // ------------------------------------------------------------
              vIpAddress   := VarArrayCreate([0, 0], varVariant);
              vIpAddress[0]:= aIp;
              vSubnetMask  := VarArrayCreate([0, 0], varVariant);
              vSubnetMask[0]:=  aSubNetMask;

              if FWbemObject.EnableStatic(vIPAddress, vSubnetMask) = 0 then
              begin
                ShowMessage( 'statik değilmiş, statik yapalım...' );
                FOutParams := FWbemObject.EnableStatic(vIpAddress, vSubnetMask);

                if FOutParams = 0
                  then
                    showmessage('İşlem tamam REBOOT gerekmez...')
                else
                if FOutParams = 1
                  then
                    showmessage('İşlem REBOOT gerektirir...');

                vDefaultIPGateway     := VarArrayCreate([0, 0], varVariant);
                vDefaultIPGateway[0]  := aDefGateway;

                vGatewayCostMetric    := VarArrayCreate([0, 0], varVariant);
                vGatewayCostMetric[0] := 1;

                FWbemObject.SetGateways(vDefaultIPGateway, vGatewayCostMetric);
                VarClear(vDefaultIPGateway);
                VarClear(vGatewayCostMetric);
              end;
              VarClear(vIPAddress);
              VarClear(vSubnetMask);
              // ------------------------------------------------------------

              LExit := TRUE;
            end;
        inc(i);
      end;
    end;
    FWbemObject:=Unassigned;
  end;
end;




Kullanımı : // parametreler default verilenler benim bilgisayara göre çalıştı kontrol edildi.


procedure TForm1.BitBtn1Click(Sender: TObject);
begin

   ChangeIp( '192.168.1.141', '255.255.255.0', '192.168.1.100' );

end;

(08-08-2024, Saat: 16:02)mcuyan Adlı Kullanıcıdan Alıntı: [ -> ]Hocam yorum ve örnekleriniz muazzam derece de güzel ve açıklayıcı.

Fakat maalesefki remote bağlantı modemden port açılımı vs işleri için Ana Pc nin ip si sabit ve o ip nin modeme port ile birlikte route edilmesi gerekmekte.

Kısacası sabit ip yi tanımlamam gerekiyor ana pc ye.

Problemi, local ağda çalışan bir sistem olarak algıladım ve yukarıdaki önerim bu yapı içindi. Sizin ihtiyacınız, Ana makine dediğiniz pcnin IPsi bir şekilde değiştiğinde, ayarlanan eski statik haline getirmek. Sanırım bu sefer doğru anladım Smile

@mrmarman  beyin paylaştığı kodları deneyip müjdeli haberi verirsiniz Smile
(08-08-2024, Saat: 19:53)frmman Adlı Kullanıcıdan Alıntı: [ -> ]@mrmarman  beyin paylaştığı kodları deneyip müjdeli haberi verirsiniz Smile

Umarım bu sihir tutar, tutmazsa
Telekoma gidip IP yi sabitlemesi gerekecek smile.pngsmile.pngsmile.png
Sayfalar: 1 2