::: 델파이 Tip&Trick :::

델파이 Tip&Trick 성격에 맞지 않는 광고,비방,질문의 글은 즉시 삭제하며
내용을 복사하여 사용할 경우 반드시 이곳(http://www.howto.pe.kr)을 출처로 명시하여 주세요


Category

  김영대(2003-03-07 20:54:40, Hit : 6267, Vote : 1569
 Network Adaptor 가 여러개인 경우의 IP 구하기

// I have need to access the IP address on Win95/WinNT
// where we have TCP/IP on the network card, and also
// on a dial-up connection.
//
// The NM* internet controls have a property 'LocalIP',
// but this returns the address of the NIC, not the dial-up.
//
// How do I get the other IP address, or better still, how
// would I loop through all adaptors ?

// 테스트 결과 Windows NT 에서만 정확히 작동했음(ws2_32.dll 의 버전은 4.00 이었음)
// Windows 95(ws2_32.dll 의 버전은 4.10.1656 이었음) 는 정확히 동작 안함
// longword 형이 없어서 longint 로 대체하여 컴파일 해보았음

unit NetCardsUnit;

interface

uses Windows, Classes, WinSock;

const
  MAX_PROTOCOL_CHAIN  = 7;
  WSAPROTOCOL_LEN     = 255;
  SIO_GET_INTERFACE_LIST = IOC_OUT or
                           ((longint(sizeOf(longint)) and IOCPARM_MASK) shl 16) or
                           (longint(byte('t')) shl 8) or 127;

type
  PINTERFACE_INFO = ^TINTERFACE_INFO;
  TINTERFACE_INFO = packed record
    iiFlags: longint;
    iiAddress: TSockAddrIn;
    iiBroadcastAddress: TSockAddrIn;
    iiNetmask: TSockAddrIn;
  end;

  TGroup            = integer;
  PGroup            = ^TGroup;
  LPWSAOVERLAPPED   = POverlapped;

  PWSAPROTOCOLCHAIN = ^TWSAPROTOCOLCHAIN;
  TWSAPROTOCOLCHAIN = packed record
    ChainLen: integer;  { the length of the chain,     }
                        { length = 0 means layered protocol, }
                        { length = 1 means base protocol,}
                        { length > 1 means protocol chain}
    ChainEntries : array[0..MAX_PROTOCOL_CHAIN-1] of Longword; { a list of dwCatalogEntryIds }
  end;

  PWSAPROTOCOL_INFOA = ^TWSAPROTOCOL_INFOA;
  TWSAPROTOCOL_INFOA = packed record
    dwServiceFlags1      : longword;
    dwServiceFlags2      : longword;
    dwServiceFlags3      : longword;
    dwServiceFlags4      : longword;
    dwProviderFlags      : longword;
    ProviderId           : TGUID;
    dwCatalogEntryId     : longword;
    ProtocolChain        : TWSAPROTOCOLCHAIN;
    iVersion             : integer;
    iAddressFamily       : integer;
    iMaxSockAddr         : integer;
    iMinSockAddr         : integer;
    iSocketType          : integer;
    iProtocol            : integer;
    iProtocolMaxOffset   : integer;
    iNetworkByteOrder    : integer;
    iSecurityScheme      : integer;
    dwMessageSize        : longword;
    dwProviderReserved   : longword;
    szProtocol           : array [0..WSAPROTOCOL_LEN+1-1] of char;
  end;

  PWSAOVERLAPPED_COMPLETION_ROUTINE = procedure(dwError:longword;
                                                cbTransferred:longword; lpOverlapped:LPWSAOVERLAPPED;
                                                dwFlags:longword); stdcall;

  function WSASocket(af:integer; atype:integer; protocol:integer;
                     lpProtocolInfo:PWSAPROTOCOL_INFOA; g:TGroup; dwFlags:longword):TSocket; stdcall;

  function WSAIoctl(s:TSocket; dwIoControlCode:longword; lpvInBuffer:Pointer;
                    cbInBuffer:longword; lpvOutBuffer:Pointer; cbOutBuffer:longword;
                    lpcbBytesReturned:Plongword; lpOverlapped:LPWSAOVERLAPPED;
                    lpCompletionRoutine:PWSAOVERLAPPED_COMPLETION_ROUTINE):integer; stdcall;

type
  TNetCardData = class
    private
    public
      socket: TSocket;
      numInterfaceCards: integer;
      ipAddress: array [1..21] of string;
      interfaceList: array [0..20] of TINTERFACE_INFO;
      constructor Create;
      function GetNumOfInterfaces: integer;virtual;
  end;

implementation

const
  winsocket = 'ws2_32.dll';

  function WSASocket;    external     winsocket name 'WSASocketA';
  function WSAIoctl;     external     winsocket name 'WSAIoctl';

constructor TNetCardData.Create;
var
  wsadata: TWSAData;
  err,i,reOrder: integer;
begin
  numInterfaceCards:=-1;
  try
    err := WSAStartup($202,wsadata);
    if (err = 0) then
    begin
      numInterfaceCards := GetNumOfInterfaces;    // this really gets all of the data
      if numInterfaceCards <> -1 then
      begin
        reOrder := 1;
        for i := numInterfaceCards-1 downTo 1  do // I do not want the self address of 127.0.0.1
        begin
          ipAddress[reOrder] := inet_ntoa(TSockAddrIn(interfaceList[i-1].iiAddress).sin_Addr);
          reOrder := succ(reOrder);    // the cards are in the interfacelist high to low.
        end;                           // I want the order to be low to high.
      end;
      numInterfaceCards := numInterfaceCards-1;    // I do not want the self address of 127.0.0.1
    end;
  finally
    WSACleanup;
  end;
end;

function TNetCardData.GetNumOfInterfaces:integer;
var
  err: integer;
  nBytesReturned: longint;
begin
  result := -1;
  socket := WSASocket(AF_INET,SOCK_DGRAM,0,nil,0,0);
  if socket = SOCKET_ERROR then
    Exit;
  err := WSAIoctl(socket, SIO_GET_INTERFACE_LIST, nil, 0,
                  @interfaceList, sizeOf(interfaceList), @nBytesReturned, nil, nil);
  if err = 0 then
    result := nBytesReturned div sizeOf(TINTERFACE_INFO);
  closesocket(socket);
end;

end.





411   [일반/컴포넌트] 윈도우즈 메모장의 편집내용을 가져오기  김영대 2003/03/07 4003 1095
410   [윈도우즈 API] 윈도우즈"시작" 버튼 Disable/Enable  김영대 2003/03/07 4549 1210
409   [윈도우즈 API] TaskBar의 다양한 기능제어  김영대 2003/03/07 5256 3432
408   [시스템] 윈도우즈 전체의 키보드 입력 금지  김영대 2003/03/07 4582 1228
407   [데이터베이스] SQL실행시의 모래시계를 표시하지 않는 방법  김영대 2003/03/07 4670 1154
406   [윈도우즈 API] 커서(케럿)의 깜박임 속도를 변경하기  김영대 2003/03/07 4822 1270
405   [데이터베이스] 데이타베이스 로그인(login) 화면 띄우기  김영대 2003/03/07 4104 1030
404   [일반/컴포넌트] 간단히 화면 하드카피(snapshot) 하기  김영대 2003/03/07 4792 1149
403   [윈도우즈 API] 스크린 세이버의 기동시간 바꾸기  김영대 2003/03/07 4318 1309
402   [시스템] 폴더의 변경여부를 감시하기  김영대 2003/03/07 5792 1285
401   [일반/컴포넌트] 전각문자인지 반각문자인지 검사하기  김영대 2003/03/07 6750 1261
400   [일반/컴포넌트] 문자열의 바이트수가 아닌 실제 글자수 구하기  김영대 2003/03/07 5023 1142
399   [일반/컴포넌트] 임시파일명 자동으로 생성하기  김영대 2003/03/07 5218 1664
398   [데이터베이스] DBGrid의 수직이동 막대 감추기  김영대 2003/03/07 4827 1239
397   [시스템] 프린터 리스트를 구하여 기본 프린터 변경하기  김영대 2003/03/07 13186 1294
396   [일반/컴포넌트] 타이틀바 클릭시 사용자 팝업메뉴 보이기  김영대 2003/03/07 4901 1180
395   [윈도우즈 API] 폼을 최하위(?)로 설정하기  김영대 2003/03/07 4846 1277
394   [시스템] 시스템에 등록된 한글폰트의 리스트  김영대 2003/03/07 5265 1547
393   [일반/컴포넌트] StringGrid 의 BeginUpdate/EndUpdate ?  김영대 2003/03/07 5475 1171
392   [윈도우즈 API] 바탕화면 아이콘의 글자색 바꾸기  김영대 2003/03/07 5148 1300
391   [윈도우즈 API] 스크린 세이버 비밀번호 알아내기  김영대 2003/03/07 4892 1203
390   [일반/컴포넌트] 파일에서 특정 Byte 모두 찾기  김영대 2003/03/07 4522 1156
  [네트웍/인터넷] Network Adaptor 가 여러개인 경우의 IP 구하기  김영대 2003/03/07 6267 1569
388   [시스템] 프린트 스풀러 제어방법  김영대 2003/03/07 6590 1882
387   [윈도우즈 API] 바탕화면 아이콘의 글자색 바꾸기2  김영대 2003/03/07 5202 1467
386   [일반/컴포넌트] 베쥬(Bezier) 곡선 그리기  김영대 2003/03/07 4823 1439
385   [윈도우즈 API] 정의되지 않은 Alt+키 입력시 Beep음 제거  김영대 2003/03/07 4376 1234
384   [일반/컴포넌트] 부활절 달걀(easter egg) 문자열 입력받기  김영대 2003/03/07 4807 1158
383   [시스템] Delphi VCL 사용안하고 프로그램 만들기  김영대 2003/03/07 5288 1329
382   [윈도우즈 API] CTRL+ALT+DEL 에 나타나지 않는 프로그램  김영대 2003/03/07 5172 1292
381   [일반/컴포넌트] 베쥬(Bezier) 곡선 그리기2  김영대 2003/03/07 4866 1160
380   [시스템] 키보드 자동반복지연 읽기/설정  김영대 2003/03/07 4677 1192
379   [시스템] 키보드 자동반복속도 읽기/설정  김영대 2003/03/07 5458 1492
378   [시스템] 윈도우즈 캡션의 높이 읽기/설정  김영대 2003/03/07 4455 1218
377   [일반/컴포넌트] ListView 의 column header 오른쪽에 이미지 넣기  김영대 2003/03/07 4981 1210
376   [일반/컴포넌트] Delphi 4 Secret Registry Settings  김영대 2003/03/07 6443 1581
375   [데이터베이스] Record Lock 검사  김영대 2003/03/07 4303 1123
374   [윈도우즈 API] 즐겨찾기 폴더의 파일에서 URL 뽑아내기  김영대 2003/03/07 5294 1299
373   [시스템] CD-ROM의 변경여부를 감시하기  김영대 2003/03/07 5006 1309
372   [시스템] Locking/ Unlocking floppy driver or CD  김영대 2003/03/07 4298 1222

[이전 10개] [1]..[11][12][13][14] 15 [16][17][18][19][20]..[25] [다음 10개]
 

Copyright 1999-2022 Zeroboard / skin by zero