본문 바로가기

카테고리 없음

[네트웍/인터넷] TClientSocket 에 Local IP 바인딩하기

// TClientSocket 의 경우 Local IP를 바인딩할 수 있는 프로퍼티가 public으로
// 설정되있지 않으므로 OnLookup 이벤트에서 bind 합니다

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Winsock, ScktComp;

type
  TForm1 = class(TForm)
    ClientSocket1: TClientSocket;
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure ClientSocket1Lookup(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Command: string;
  retBuf: array [0 .. 4095] of Char;
  iReturn: Integer;
begin
  Memo1.Clear;
  
  with ClientSocket1 do
  begin
    Host := 'www.ucware.net';
    ClientType := ctBlocking;
    Port := 80;

    try
      Open;
      Command := 'GET / HTTP/1.1'#13#10+'Host: www.ucware.net'#13#10#13#10;
      iReturn := Socket.SendBuf(Pointer(Command)^, Length(Command));
      if iReturn > 0 then
      begin
        while iReturn > 0 do
        begin
          FillChar(retBuf, SizeOf(retBuf), 0);
          iReturn := Socket.ReceiveBuf(retBuf, SizeOf(retBuf));
          if iReturn > 0 then
            Memo1.Lines.Add(retBuf);
        end;
      end else
        raise Exception.Create('Server not responding!');
    except
      on E: Exception do
        ShowMessage('Error at ' + E.Message);
    end;
  end;
end;

procedure TForm1.ClientSocket1Lookup(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Addr: TSockAddr;
begin
  FillChar(Addr, 0, SizeOf(Addr));

  Addr.sin_family := AF_INET;
  Addr.sin_port := htons(0); // Local Port를 0으로 하면 OS에서 random 할당
  Addr.sin_addr.s_addr := inet_addr('192.168.10.102'); // Local IP를 바인딩한다

  if bind(TSocket(Socket.SocketHandle), Addr, SizeOf(Addr)) <> 0 then
  begin
    if WSAGetLastError <> WSAEWOULDBLOCK then
      raise ESocketError.Create('cannot bind to a local ip/port');
  end;
end;
  
end.