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

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


Category

  김영대(2003-03-07 20:54:40, Hit : 6134, Vote : 1528
 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.





611   [윈도우즈 API] DDE를 사용하여 IE, Netscape의 현재 URL 가져오기  김영대 2003/03/07 4569 1238
610   [윈도우즈 API] 데스크탑에 있는 아이콘의 갯수 구하기  김영대 2003/03/07 4180 1144
609   [일반/컴포넌트] design mode 인지 검사하기  김영대 2003/03/07 5725 1463
608   [네트웍/인터넷] 프린터의 용지 크기/공급 설정하기  김영대 2003/03/07 6925 1272
607   [시스템] 프린터의 "용지 공급" 리스트 구하기  김영대 2003/03/07 4690 1351
606   [네트웍/인터넷] Read/Write to COM Port  김영대 2003/03/07 4823 1143
605   [일반/컴포넌트] Button의 Mouse Down/Up 흉내내기  김영대 2003/03/07 4357 1126
604   [일반/컴포넌트] 두 StringGrid 의 scroll 을 동기화 시키기  김영대 2003/03/07 4407 1071
603   [일반/컴포넌트] 해상도(screen resolution)를 변경했는지 검사  김영대 2003/03/07 4592 1298
602   [일반/컴포넌트] StringGrid의 선택된 Cell을 버튼으로 보이기  김영대 2003/03/07 4397 1091
601   [윈도우즈 API] Windows NT 도메인명 가져오기  김영대 2003/03/07 5638 1486
600   [시스템] Locking/ Unlocking floppy driver or CD  김영대 2003/03/07 4186 1185
599   [시스템] CD-ROM의 변경여부를 감시하기  김영대 2003/03/07 4905 1277
598   [윈도우즈 API] 즐겨찾기 폴더의 파일에서 URL 뽑아내기  김영대 2003/03/07 5144 1260
597   [데이터베이스] Record Lock 검사  김영대 2003/03/07 4206 1092
596   [일반/컴포넌트] Delphi 4 Secret Registry Settings  김영대 2003/03/07 6299 1547
595   [일반/컴포넌트] ListView 의 column header 오른쪽에 이미지 넣기  김영대 2003/03/07 4845 1176
594   [시스템] 윈도우즈 캡션의 높이 읽기/설정  김영대 2003/03/07 4358 1186
593   [시스템] 키보드 자동반복속도 읽기/설정  김영대 2003/03/07 5352 1456
592   [시스템] 키보드 자동반복지연 읽기/설정  김영대 2003/03/07 4567 1156
591   [일반/컴포넌트] 베쥬(Bezier) 곡선 그리기2  김영대 2003/03/07 4681 1117
590   [윈도우즈 API] CTRL+ALT+DEL 에 나타나지 않는 프로그램  김영대 2003/03/07 5023 1259
589   [시스템] Delphi VCL 사용안하고 프로그램 만들기  김영대 2003/03/07 5121 1264
588   [일반/컴포넌트] 부활절 달걀(easter egg) 문자열 입력받기  김영대 2003/03/07 4635 1075
587   [윈도우즈 API] 정의되지 않은 Alt+키 입력시 Beep음 제거  김영대 2003/03/07 4260 1189
586   [일반/컴포넌트] 베쥬(Bezier) 곡선 그리기  김영대 2003/03/07 4713 1404
585   [윈도우즈 API] 바탕화면 아이콘의 글자색 바꾸기2  김영대 2003/03/07 5080 1432
584   [시스템] 프린트 스풀러 제어방법  김영대 2003/03/07 6415 1809
  [네트웍/인터넷] Network Adaptor 가 여러개인 경우의 IP 구하기  김영대 2003/03/07 6134 1528
582   [일반/컴포넌트] 파일에서 특정 Byte 모두 찾기  김영대 2003/03/07 4415 1124
581   [윈도우즈 API] 스크린 세이버 비밀번호 알아내기  김영대 2003/03/07 4796 1171
580   [윈도우즈 API] 바탕화면 아이콘의 글자색 바꾸기  김영대 2003/03/07 5046 1261
579   [일반/컴포넌트] StringGrid 의 BeginUpdate/EndUpdate ?  김영대 2003/03/07 5282 1138
578   [시스템] 시스템에 등록된 한글폰트의 리스트  김영대 2003/03/07 5120 1511
577   [윈도우즈 API] 폼을 최하위(?)로 설정하기  김영대 2003/03/07 4660 1241
576   [일반/컴포넌트] 타이틀바 클릭시 사용자 팝업메뉴 보이기  김영대 2003/03/07 4773 1147
575   [시스템] 프린터 리스트를 구하여 기본 프린터 변경하기  김영대 2003/03/07 5310 1244
574   [데이터베이스] DBGrid의 수직이동 막대 감추기  김영대 2003/03/07 4660 1204
573   [일반/컴포넌트] 임시파일명 자동으로 생성하기  김영대 2003/03/07 5124 1628
572   [일반/컴포넌트] 문자열의 바이트수가 아닌 실제 글자수 구하기  김영대 2003/03/07 4839 1105

[1][2][3][4][5][6][7][8][9] 10 ..[25] [다음 10개]
 

Copyright 1999-2021 Zeroboard / skin by zero