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

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


Category

  김영대(2003-03-07 20:54:40, Hit : 6011, Vote : 1488
 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 4458 1215
610   [윈도우즈 API] 데스크탑에 있는 아이콘의 갯수 구하기  김영대 2003/03/07 4078 1117
609   [일반/컴포넌트] design mode 인지 검사하기  김영대 2003/03/07 5550 1419
608   [네트웍/인터넷] 프린터의 용지 크기/공급 설정하기  김영대 2003/03/07 6505 1226
607   [시스템] 프린터의 "용지 공급" 리스트 구하기  김영대 2003/03/07 4605 1326
606   [네트웍/인터넷] Read/Write to COM Port  김영대 2003/03/07 4678 1119
605   [일반/컴포넌트] Button의 Mouse Down/Up 흉내내기  김영대 2003/03/07 4273 1101
604   [일반/컴포넌트] 두 StringGrid 의 scroll 을 동기화 시키기  김영대 2003/03/07 4246 1027
603   [일반/컴포넌트] 해상도(screen resolution)를 변경했는지 검사  김영대 2003/03/07 4463 1271
602   [일반/컴포넌트] StringGrid의 선택된 Cell을 버튼으로 보이기  김영대 2003/03/07 4297 1067
601   [윈도우즈 API] Windows NT 도메인명 가져오기  김영대 2003/03/07 5552 1461
600   [시스템] Locking/ Unlocking floppy driver or CD  김영대 2003/03/07 4066 1155
599   [시스템] CD-ROM의 변경여부를 감시하기  김영대 2003/03/07 4835 1250
598   [윈도우즈 API] 즐겨찾기 폴더의 파일에서 URL 뽑아내기  김영대 2003/03/07 5033 1223
597   [데이터베이스] Record Lock 검사  김영대 2003/03/07 4100 1061
596   [일반/컴포넌트] Delphi 4 Secret Registry Settings  김영대 2003/03/07 6107 1513
595   [일반/컴포넌트] ListView 의 column header 오른쪽에 이미지 넣기  김영대 2003/03/07 4716 1155
594   [시스템] 윈도우즈 캡션의 높이 읽기/설정  김영대 2003/03/07 4270 1163
593   [시스템] 키보드 자동반복속도 읽기/설정  김영대 2003/03/07 5248 1420
592   [시스템] 키보드 자동반복지연 읽기/설정  김영대 2003/03/07 4466 1133
591   [일반/컴포넌트] 베쥬(Bezier) 곡선 그리기2  김영대 2003/03/07 4570 1095
590   [윈도우즈 API] CTRL+ALT+DEL 에 나타나지 않는 프로그램  김영대 2003/03/07 4931 1230
589   [시스템] Delphi VCL 사용안하고 프로그램 만들기  김영대 2003/03/07 5001 1236
588   [일반/컴포넌트] 부활절 달걀(easter egg) 문자열 입력받기  김영대 2003/03/07 4539 1048
587   [윈도우즈 API] 정의되지 않은 Alt+키 입력시 Beep음 제거  김영대 2003/03/07 4201 1169
586   [일반/컴포넌트] 베쥬(Bezier) 곡선 그리기  김영대 2003/03/07 4644 1379
585   [윈도우즈 API] 바탕화면 아이콘의 글자색 바꾸기2  김영대 2003/03/07 4971 1393
584   [시스템] 프린트 스풀러 제어방법  김영대 2003/03/07 6140 1770
  [네트웍/인터넷] Network Adaptor 가 여러개인 경우의 IP 구하기  김영대 2003/03/07 6011 1488
582   [일반/컴포넌트] 파일에서 특정 Byte 모두 찾기  김영대 2003/03/07 4354 1102
581   [윈도우즈 API] 스크린 세이버 비밀번호 알아내기  김영대 2003/03/07 4730 1146
580   [윈도우즈 API] 바탕화면 아이콘의 글자색 바꾸기  김영대 2003/03/07 4963 1233
579   [일반/컴포넌트] StringGrid 의 BeginUpdate/EndUpdate ?  김영대 2003/03/07 4966 1112
578   [시스템] 시스템에 등록된 한글폰트의 리스트  김영대 2003/03/07 5010 1484
577   [윈도우즈 API] 폼을 최하위(?)로 설정하기  김영대 2003/03/07 4504 1215
576   [일반/컴포넌트] 타이틀바 클릭시 사용자 팝업메뉴 보이기  김영대 2003/03/07 4583 1118
575   [시스템] 프린터 리스트를 구하여 기본 프린터 변경하기  김영대 2003/03/07 5174 1217
574   [데이터베이스] DBGrid의 수직이동 막대 감추기  김영대 2003/03/07 4449 1164
573   [일반/컴포넌트] 임시파일명 자동으로 생성하기  김영대 2003/03/07 5050 1599
572   [일반/컴포넌트] 문자열의 바이트수가 아닌 실제 글자수 구하기  김영대 2003/03/07 4604 1074

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

Copyright 1999-2019 Zeroboard / skin by zero