How to use
var
conn: TLocalBindingConnection;
begin
StartupSocket();
conn := TLocalBindingConnection.Create();
try
conn.NetworkStream := TclNetworkStream.Create();
conn.OpenWithBinding('11.22.33.44', 123, '192.168.1.1', 54301);
ShowMessage(conn.ReadString());
conn.Close(False);
finally
conn.Free();
CleanupSocket();
end;
end;
Implementation
1. Create a new TLocalBindingConnection object.
type
TLocalBindingConnection = class(TclTcpClientConnection)
private
FAbortEvent: THandle;
FTimeOutTicks: Integer;
procedure InitTimeOutTicks;
protected
procedure DoDestroy; override;
public
constructor Create;
procedure Abort; override;
procedure OpenWithBinding(const AIP: string; APort: Integer;
const ALocalBindingIP: string; ALocalBindingPort: Integer);
end;
2. Define the OpenWithBinding method.
procedure TLocalBindingConnection.OpenWithBinding(const AIP: string; APort: Integer;
const ALocalBindingIP: string; ALocalBindingPort: Integer);
var
res: Integer;
networkEvents: TWSANetworkEvents;
isReadIntilCloseOld: Boolean;
addr, bindAddr: TclIPAddress;
begin
addr := nil;
bindAddr := nil;
try
addr := TclIPAddress.CreateIpAddress(AIP);
isReadIntilCloseOld := IsReadUntilClose;
IsReadUntilClose := False;
CreateSocket(addr.AddressFamily, SOCK_STREAM, IPPROTO_TCP);
SelectSocketEvent(FD_CONNECT);
bindAddr := TclIPAddress.CreateBindingIpAddress(ALocalBindingIP, addr.AddressFamily);
NetworkStream.Bind(bindAddr, ALocalBindingPort);
if not NetworkStream.Connect(addr, APort) then
begin
InitTimeOutTicks();
repeat
if WaitForEvent(SocketEvent, FAbortEvent, FTimeOutTicks, TimeOut) then
begin
res := WSAEnumNetworkEvents(Socket.Socket, SocketEvent, @networkEvents);
if (res = SOCKET_ERROR) then
begin
RaiseSocketError(WSAGetLastError());
end;
if ((networkEvents.lNetworkEvents and FD_CONNECT) > 0) then
begin
if (networkEvents.iErrorCode[FD_CONNECT_BIT] <> 0) then
begin
RaiseSocketError(networkEvents.iErrorCode[FD_CONNECT_BIT]);
end;
Break;
end;
end;
until IsAborted;
end;
SelectSocketEvent(FD_READ or FD_CLOSE or FD_WRITE);
if IsAborted then
begin
Close(False);
end else
begin
SetActive(True);
DispatchNextAction();
if not Active then
begin
RaiseSocketError(ConnectionClosed, ConnectionClosedCode);
end;
NetworkStream.ConnectEnd();
NetworkStream.StreamReady();
end;
IsReadUntilClose := isReadIntilCloseOld;
finally
bindAddr.Free();
addr.Free();
end;
end;
Article ID: 101, Created: December 27, 2017 at 2:11 PM, Modified: March 16, 2020 at 10:02 PM