MySocket.pas
资源名称:DarkMoon.rar [点击查看]
上传用户:hndmjx
上传日期:2014-09-16
资源大小:3369k
文件大小:41k
源码类别:
Delphi控件源码
开发平台:
Delphi
- unit MySocket;
- {(C) Alex Demchenko(alex@ritlabs.com)}
- {$R-} //Remove range checking
- {$DEFINE USE_FORMS} //If you don't use forms unit remove this line
- {$DEFINE REMOVEHTTP}
- interface
- uses
- Windows, Messages, WinSock, {$IFDEF USE_FORMS}Forms, {$ENDIF} Classes, ICQWorks;
- function InitMySocket(var WSA: TWSAData): LongWord;
- procedure FinalMySocket;
- const
- CNetPktLen = 8192;
- type
- {$IFNDEF USE_FORMS}
- TWndMethod = procedure(var Message: TMessage) of object;
- {$ENDIF}
- TOnRecv = procedure(Sender: TObject; Socket: TSocket; Buffer: Pointer; BufLen: LongWord) of object;
- TOnPktParse = procedure(Sender: TObject; Buffer: Pointer; BufLen: LongWord) of object;
- TOnPktParseAdv = procedure(Sender: TObject; Buffer: Pointer; BufLen: LongWord; Incoming: Boolean) of object;
- TOnAdvPktParse = procedure(Sender: TObject; Buffer: Pointer; BufLen: LongWord; Incoming: Boolean) of object;
- TOnResolve = procedure(Sender: TObject; Addr: String) of object;
- TOnError = procedure(Sender: TObject; ErrorType: TErrorType; ErrorMsg: String) of object;
- PNetPacket = ^TNetPacket;
- TNetPacket = record
- Buf: array[0..CNetPktLen - 1] of Byte;
- BufLen: Word;
- Offset: Word;
- Next: PNetPacket;
- end;
- TNetBuffer = class(TObject)
- private
- FPkt: PNetPacket;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Clear;
- procedure AddPacket(Buffer: Pointer; BufLen: LongWord);
- procedure DelPacket;
- function GetPacket(Buffer: Pointer): LongWord;
- function SkipData(Len: Word): Boolean;
- procedure AddStr(Value: String);
- function GetStr: String;
- end;
- TClSock = class(TObject)
- private
- FWndHandle: THandle;
- FIp: String;
- FDestPort: LongWord;
- FClSock: TSocket;
- FOnRecv: TOnRecv;
- FOnDisconnect: TNotifyEvent;
- FOnConnect: TNotifyEvent;
- FOnConnectError: TNotifyEvent;
- FOnPktParse: TOnPktParse;
- FHostIp: array[0..MAXGETHOSTSTRUCT - 1] of Char;
- FResolve: Boolean;
- FOnResolve: TOnResolve;
- FOnFailed: TNotifyEvent;
- FOnError: TOnError;
- FCanWrite: Boolean;
- FBuffer: TNetBuffer;
- FOnDataSent: TNotifyEvent;
- function ResolveAddr(Value: Pointer): LongInt;
- function TestResolve(IP: String): Boolean;
- procedure InitConnect(dwIP: LongWord);
- procedure OnSockMsg(var Msg: TMessage);
- function IsConnected: Boolean;
- procedure ProcessBuffer;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Connect(ClearBuffer: Boolean = True); //Connect to remote host
- procedure Resolve; //Just resolve remote host w/o connecting
- procedure DoClose; //Close socket
- procedure Disconnect;
- procedure SendData(var Buf; BufLen: LongWord);
- procedure SendStr(const Value: String);
- property IP: String read FIp write FIp;
- property DestPort: LongWord read FDestPort write FDestPort;
- property Connected: Boolean read IsConnected;
- property WndHandle: THandle read FWndHandle;
- published
- property OnDataSent: TNotifyEvent read FOnDataSent write FOnDataSent;
- property OnRecieve: TOnRecv read FOnRecv write FOnRecv;
- property OnDisconnect: TNotifyEvent read FOnDisconnect write FOnDisconnect;
- property OnConnect: TNotifyEvent read FOnConnect write FOnConnect;
- property OnConnectError: TNotifyEvent read FOnConnectError write FOnConnectError;
- property OnPktParse: TOnPktParse read FOnPktParse write FOnPktParse;
- property OnResolve: TOnResolve read FOnResolve write FOnResolve;
- property OnResolveFailed: TNotifyEvent read FOnFailed write FOnFailed;
- property OnError: TOnError read FOnError write FOnError;
- end;
- TProxySock = class(TObject)
- private
- {$IFNDEF REMOVEHTTP}
- FICQRecv: TClSock;
- FICQSID: String;
- FICQSEQ: Word;
- FICQPIP: String;
- FICQPPORT: Word;
- FBuf: array[0..$FFFF - 1] of Byte; //
- FCurLen: Word; // HTTP Protocol
- FLen: Word; //
- {$ENDIF}
- FSrcBuf: array[0..MAX_DATA_LEN - 1] of Byte;
- FSrcLen: Word;
- FSock: TClSock;
- FProxyType: TProxyType;
- FProxyHost: String;
- FProxyPort: Word;
- FProxyAuth: Boolean;
- FProxyPass: String;
- FUserID: String;
- FHost: String;
- FPort: Word;
- FResolve: Boolean;
- FSocks: Word;
- FOnConnectError: TNotifyEvent;
- FOnDisconnect: TNotifyEvent;
- FOnPktParse: TOnAdvPktParse;
- FOnError: TOnError;
- FOnRecv: TOnRecv;
- FOnConnectProc: TNotifyEvent;
- private
- {$IFNDEF REMOVEHTTP}
- procedure HandleHTTPDataPak(Buffer: Pointer; BufLen: LongWord);
- procedure SendHTTPData(Buffer: Pointer; BufLen: LongWord);
- procedure HandleHTTPData(Buffer: Pointer; BufLen: LongWord);
- {$ENDIF}
- function GetWndHandle: THandle;
- {$IFNDEF REMOVEHTTP}
- procedure InitRecvConnection;
- procedure OnHTTPRecvSockConnect(Sender: TObject);
- procedure OnHTTPDataSent(Sender: TObject);
- {$ENDIF}
- procedure OnSockResolve(Sender: TObject; Addr: String);
- procedure OnSockResolveFailed(Sender: TObject);
- procedure OnSockConnect(Sender: TObject);
- procedure OnSockRecv(Sender: TObject; Socket: TSocket; Buffer: Pointer; BufLen: LongWord);
- procedure OnSockConnectError(Sender: TObject);
- procedure OnSockDisconnect(Sender: TObject);
- procedure OnSockError(Sender: TObject; ErrorType: TErrorType; ErrorMsg: String);
- procedure OnPktParse(Sender: TObject; Buffer: Pointer; BufLen: LongWord);
- protected
- procedure OnReceive(Buffer: Pointer; BufLen: LongWord); dynamic;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Connect; dynamic;
- procedure Disconnect;
- procedure SendData(var Buf; BufLen: LongWord);
- property Host: String read FHost write FHost;
- property Port: Word read FPort write FPort;
- property ProxyType: TProxyType read FProxyType write FProxyType;
- property ProxyHost: String read FProxyHost write FProxyHost;
- property ProxyPort: Word read FProxyPort write FProxyPort;
- property ProxyUserID: String read FUserID write FUserID;
- property ProxyAuth: Boolean read FProxyAuth write FProxyAuth;
- property ProxyPass: String read FProxyPass write FProxyPass;
- property UseProxyResolve: Boolean read FResolve write FResolve default False;
- property WndHandle: THandle read GetWndHandle;
- published
- property OnConnectError: TNotifyEvent read FOnConnectError write FOnConnectError;
- property OnDisconnect: TNotifyEvent read FOnDisconnect write FOnDisconnect;
- property OnPktParseA: TOnAdvPktParse read FOnPktParse write FOnPktParse;
- property OnError: TOnError read FOnError write FOnError;
- property OnReceiveProc: TOnRecv read FOnRecv write FOnRecv;
- property OnConnectProc: TNotifyEvent read FOnConnectProc write FOnConnectProc;
- end;
- TMySock = class(TProxySock)
- private
- function GetClientSocket: TSocket;
- procedure SetClientSocket(Socket: TSocket);
- function IsConnected: Boolean;
- public
- property ClientSocket: TSocket read GetClientSocket write SetClientSocket;
- property Connected: Boolean read IsConnected;
- end;
- TOnClientConnected = procedure(Sender: TObject; Socket: TMySock) of object;
- TSrvSock = class(TObject)
- private
- FPort: Word;
- FWndHandle: THandle;
- FSrvSock: TSocket;
- FOnClientConnected: TOnClientConnected;
- procedure OnSockMsg(var Msg: TMessage);
- public
- constructor Create;
- destructor Destroy; override;
- function StartServer(Port: Word): Boolean;
- function StopServer: Boolean;
- property Port: Word read FPort;
- published
- property OnClientConnected: TOnClientConnected read FOnClientConnected write FOnClientConnected;
- end;
- var
- WSA: TWSAData;
- function GetLocalIP: LongInt;
- function FindBindPort: Word;
- {$IFNDEF USE_FORMS}
- function AllocateHWnd(Method: TWndMethod): THandle;
- procedure DeallocateHWnd(Wnd: THandle);
- {$ENDIF}
- implementation
- const
- WSA_ACCEPT = WM_USER + $10;
- WSA_NETEVENT = WM_USER + $20;
- WSA_RESOLVE_COMPLETE = WM_USER + $30;
- b64alphabet: PChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
- function EncodeBase64(Value: String): String;
- const
- pad: PChar = '====';
- function EncodeChunk(const Chunk: String): String;
- var
- W: LongWord;
- i, n: Byte;
- begin
- n := Length(Chunk); W := 0;
- for i := 0 to n - 1 do
- W := W + Ord(Chunk[i + 1]) shl ((2 - i) * 8);
- Result := b64alphabet[(W shr 18) and $3f] +
- b64alphabet[(W shr 12) and $3f] +
- b64alphabet[(W shr 06) and $3f] +
- b64alphabet[(W shr 00) and $3f];
- if n <> 3 then
- Result := Copy(Result, 0, n + 1) + Copy(pad, 0, 3 - n); //add padding when out len isn't 24 bits
- end;
- begin
- Result := '';
- while Length(Value) > 0 do
- begin
- Result := Result + EncodeChunk(Copy(Value, 0, 3));
- Delete(Value, 1, 3);
- end;
- end;
- function DecodeBase64(Value: String): String;
- function DecodeChunk(const Chunk: String): String;
- var
- W: LongWord;
- i: Byte;
- begin
- W := 0; Result := '';
- for i := 1 to 4 do
- if Pos(Chunk[i], b64alphabet) <> 0 then
- W := W + Word((Pos(Chunk[i], b64alphabet) - 1)) shl ((4 - i) * 6);
- for i := 1 to 3 do
- Result := Result + Chr(W shr ((3 - i) * 8) and $ff);
- end;
- begin
- Result := '';
- if Length(Value) mod 4 <> 0 then Exit;
- while Length(Value) > 0 do
- begin
- Result := Result + DecodeChunk(Copy(Value, 0, 4));
- Delete(Value, 1, 4);
- end;
- end;
- constructor TNetBuffer.Create;
- begin
- inherited;
- FPkt := nil;
- end;
- destructor TNetBuffer.Destroy;
- begin
- Clear;
- inherited;
- end;
- procedure TNetBuffer.Clear;
- var
- p: Pointer;
- begin
- while FPkt <> nil do
- begin
- p := FPkt^.Next;
- FreeMem(FPkt);
- FPkt := p;
- end;
- end;
- procedure TNetBuffer.AddPacket(Buffer: Pointer; BufLen: LongWord);
- var
- p: PNetPacket;
- begin
- if BufLen > CNetPktLen then BufLen := CNetPktLen;
- if FPkt = nil then
- begin
- GetMem(FPkt, SizeOf(TNetPacket));
- p := FPkt;
- end else
- begin
- p := FPkt;
- while p <> nil do
- begin
- if p^.Next = nil then Break;
- p := p^.Next;
- end;
- GetMem(p^.Next, SizeOf(TNetPacket));
- p := p^.Next;
- end;
- p^.BufLen := BufLen;
- p^.Offset := 0;
- p^.Next := nil;
- Move(Buffer^, p^.Buf, BufLen);
- end;
- procedure TNetBuffer.DelPacket;
- var
- p: PNetPacket;
- begin
- if FPkt = nil then Exit;
- if FPkt^.Next <> nil then
- begin
- p := FPkt^.Next;
- FreeMem(FPkt);
- FPkt := p;
- end else
- begin
- FreeMem(FPkt);
- FPkt := nil;
- end;
- end;
- function TNetBuffer.GetPacket(Buffer: Pointer): LongWord;
- begin
- if (FPkt = nil) or (FPkt^.Offset >= FPkt^.BufLen) then
- begin
- Result := 0;
- Exit;
- end;
- Move(Ptr(LongWord(@FPkt^.Buf) + FPkt^.Offset)^, Buffer^, FPkt^.BufLen - FPkt^.Offset);
- Result := FPkt^.BufLen - FPkt^.Offset;
- end;
- function TNetBuffer.SkipData(Len: Word): Boolean;
- begin
- if FPkt = nil then
- begin
- Result := True;
- Exit;
- end;
- Inc(FPkt^.Offset, Len);
- Result := FPkt^.Offset >= FPkt^.BufLen;
- end;
- procedure TNetBuffer.AddStr(Value: String);
- begin
- AddPacket(@Value[1], Length(Value));
- end;
- function TNetBuffer.GetStr: String;
- var
- p: array[0..CNetPktLen] of Char;
- begin
- p[GetPacket(@p)] := #0;
- Result := PChar(@p);
- end;
- function InitMySocket(var WSA: TWSAData): LongWord;
- begin
- Result := WSAStartup(MAKEWORD(1, 1), WSA);
- end;
- procedure FinalMySocket;
- begin
- WSACleanUp;
- end;
- //////////////////////////////////////////////////////////////////////////////////////////////////////////
- {$IFNDEF USE_FORMS}
- type
- PObjectInstance = ^TObjectInstance;
- TObjectInstance = packed record
- Code: Byte;
- Offset: Integer;
- case Integer of
- 0: (Next: PObjectInstance);
- 1: (Method: TWndMethod);
- end;
- PInstanceBlock = ^TInstanceBlock;
- TInstanceBlock = packed record
- Next: PInstanceBlock;
- Code: array[1..2] of Byte;
- WndProcPtr: Pointer;
- Instances: array[0..100] of TObjectInstance;
- end;
- var
- InstBlockList: PInstanceBlock;
- InstFreeList: PObjectInstance;
- { Standard window procedure }
- { In ECX = Address of method pointer }
- { Out EAX = Result }
- function StdWndProc(Window: HWND; Message, WParam: Longint;
- LParam: Longint): Longint; stdcall; assembler;
- asm
- XOR EAX,EAX
- PUSH EAX
- PUSH LParam
- PUSH WParam
- PUSH Message
- MOV EDX,ESP
- MOV EAX,[ECX].Longint[4]
- CALL [ECX].Pointer
- ADD ESP,12
- POP EAX
- end;
- { Allocate an object instance }
- function CalcJmpOffset(Src, Dest: Pointer): Longint;
- begin
- Result := Longint(Dest) - (Longint(Src) + 5);
- end;
- function MakeObjectInstance(Method: TWndMethod): Pointer;
- const
- BlockCode: array[1..2] of Byte = (
- $59, { POP ECX }
- $E9); { JMP StdWndProc }
- PageSize = 4096;
- var
- Block: PInstanceBlock;
- Instance: PObjectInstance;
- begin
- if InstFreeList = nil then
- begin
- Block := VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- Block^.Next := InstBlockList;
- Move(BlockCode, Block^.Code, SizeOf(BlockCode));
- Block^.WndProcPtr := Pointer(CalcJmpOffset(@Block^.Code[2], @StdWndProc));
- Instance := @Block^.Instances;
- repeat
- Instance^.Code := $E8; { CALL NEAR PTR Offset }
- Instance^.Offset := CalcJmpOffset(Instance, @Block^.Code);
- Instance^.Next := InstFreeList;
- InstFreeList := Instance;
- Inc(Longint(Instance), SizeOf(TObjectInstance));
- until Longint(Instance) - Longint(Block) >= SizeOf(TInstanceBlock);
- InstBlockList := Block;
- end;
- Result := InstFreeList;
- Instance := InstFreeList;
- InstFreeList := Instance^.Next;
- Instance^.Method := Method;
- end;
- { Free an object instance }
- procedure FreeObjectInstance(ObjectInstance: Pointer);
- begin
- if ObjectInstance <> nil then
- begin
- PObjectInstance(ObjectInstance)^.Next := InstFreeList;
- InstFreeList := ObjectInstance;
- end;
- end;
- var
- UtilWindowClass: TWndClass = (
- style: 0;
- lpfnWndProc: @DefWindowProc;
- cbClsExtra: 0;
- cbWndExtra: 0;
- hInstance: 0;
- hIcon: 0;
- hCursor: 0;
- hbrBackground: 0;
- lpszMenuName: nil;
- lpszClassName: 'MySockUtilWindow'
- );
- function AllocateHWnd(Method: TWndMethod): THandle;
- var
- TempClass: TWndClass;
- ClassRegistered: Boolean;
- begin
- UtilWindowClass.hInstance := HInstance;
- ClassRegistered := GetClassInfo(HInstance, UtilWindowClass.lpszClassName,
- TempClass);
- if not ClassRegistered or (TempClass.lpfnWndProc <> @DefWindowProc) then
- begin
- if ClassRegistered then
- Windows.UnregisterClass(UtilWindowClass.lpszClassName, HInstance);
- Windows.RegisterClass(UtilWindowClass);
- end;
- Result := CreateWindow(UtilWindowClass.lpszClassName,
- '', WS_POPUP, 0, 0, 0, 0, 0, 0, HInstance, nil);
- if Assigned(Method) then
- SetWindowLong(Result, GWL_WNDPROC, Longint(MakeObjectInstance(Method)));
- end;
- procedure DeallocateHWnd(Wnd: THandle);
- var
- Instance: Pointer;
- begin
- Instance := Pointer(GetWindowLong(Wnd, GWL_WNDPROC));
- DestroyWindow(Wnd);
- if Instance <> @DefWindowProc then FreeObjectInstance(Instance);
- end;
- {$ENDIF}
- /////////////////////////////////////////////////////////////////////////////////////////////////////////
- constructor TClSock.Create;
- begin
- inherited;
- FWndHandle := AllocateHwnd(OnSockMsg);
- FClSock := INVALID_SOCKET;
- FResolve := False;
- FBuffer := TNetBuffer.Create;
- end;
- destructor TClSock.Destroy;
- begin
- DoClose;
- DeallocateHwnd(FWndHandle);
- FBuffer.Free;
- inherited;
- end;
- function TClSock.TestResolve(IP: String): Boolean;
- begin
- Result := inet_addr(PChar(IP)) <> LongInt(INADDR_NONE);
- end;
- function TClSock.ResolveAddr(Value: Pointer): LongInt;
- var
- addr: in_addr;
- hostent: PHostEnt;
- begin
- Result := -1;
- hostent := Value;
- if hostent^.h_addr_list <> nil then
- begin
- addr.S_addr := PLongInt(hostent^.h_addr_list^)^;
- Result := addr.S_addr;
- end else
- Exit;
- end;
- procedure TClSock.InitConnect(dwIP: LongWord);
- var
- dest_sin: TSockAddr;
- begin
- DoClose;
- FClSock := socket(AF_INET, SOCK_STREAM, 0);
- WSAAsyncSelect(FClSock, FWndHandle, WSA_NETEVENT, FD_CONNECT or FD_CLOSE or FD_READ or FD_WRITE);
- dest_sin.sin_family := AF_INET;
- dest_sin.sin_addr.s_addr := dwIP;
- dest_sin.sin_port := htons(FDestPort);
- if (WinSock.connect(FClSock, dest_sin, SizeOf(TSockAddr)) = SOCKET_ERROR) and (WSAGetLastError <> WSAEWOULDBLOCK) then
- begin
- DoClose;
- if Assigned(OnError) then
- FOnError(Self, ERR_SOCKET, 'connect() returned SOCKET_ERROR');
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- Exit;
- end;
- end;
- procedure TClSock.OnSockMsg(var Msg: TMessage);
- var
- rc: Integer;
- buf: array[0..1023] of Byte;
- inaddr: in_addr;
- begin
- case Msg.Msg of
- WSA_RESOLVE_COMPLETE:
- begin
- if FResolve then
- begin
- if Assigned(OnResolve) then
- begin
- if HIWORD(Msg.wParam) <> 0 then
- begin
- if Assigned(OnError) then
- FOnError(Self, ERR_SOCKET, 'Cannot resolve host');
- if Assigned(OnResolveFailed) then
- FOnFailed(Self);
- Exit;
- end;
- inaddr.S_addr := ResolveAddr(@FHostIP);
- if Assigned(OnResolve) then
- FOnResolve(Self, inet_ntoa(inaddr));
- Exit;
- end;
- end;
- if HIWORD(Msg.wParam) <> 0 then
- begin
- DoClose;
- if Assigned(OnError) then
- FOnError(Self, ERR_SOCKET, 'Cannot resolve host');
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- Exit;
- end;
- InitConnect(ResolveAddr(@FHostIP));
- end;
- WSA_NETEVENT:
- begin
- if WSAGetSelectEvent(Msg.lParam) = FD_READ then
- begin
- rc := recv(Msg.wParam, buf, SizeOf(buf) - 1, 0);
- if rc <> SOCKET_ERROR then
- begin
- if Assigned(OnRecieve) then
- FOnRecv(Self, Msg.wParam, @buf, rc);
- end else
- begin
- if Assigned(OnError) then
- FOnError(Self, ERR_SOCKET, 'Received some data, but recv() returned 0');
- Disconnect;
- end;
- Exit;
- end
- //Connection with server was lost
- else if WSAGetSelectEvent(Msg.lParam) = FD_CLOSE then
- Disconnect
- //Connection with server has been estabilished or connection error
- else if WSAGetSelectEvent(Msg.lParam) = FD_CONNECT then
- begin
- if HIWORD(Msg.lParam) = 0 then
- begin
- if Assigned(OnConnect) then
- FOnConnect(Self);
- end else
- begin
- DoClose;
- if Assigned(OnError) then
- FOnError(Self, ERR_SOCKET, 'Cannot connect: no rote to host.');
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- Exit;
- end;
- end
- else if WSAGetSelectEvent(Msg.lParam) = FD_WRITE then
- begin
- FCanWrite := True;
- ProcessBuffer;
- end;
- end else
- Msg.Result := DefWindowProc(FWndHandle, Msg.Msg, Msg.WParam, Msg.LParam);
- end;
- end;
- procedure TClSock.ProcessBuffer;
- var
- ret: Integer;
- Buf: array[0..CNetPktLen - 1] of Byte;
- begin
- if not FCanWrite then Exit;
- if FClSock <> INVALID_SOCKET then
- begin
- while True do
- begin
- ret := FBuffer.GetPacket(@Buf);
- if ret < 1 then begin if Assigned(OnDataSent) then FOnDataSent(Self); Exit; end; {All data has been sent}
- ret := send(FClSock, Buf, ret, 0);
- if ret = SOCKET_ERROR then
- begin
- if WSAGetLastError = WSAEWOULDBLOCK then
- FCanWrite := False
- else begin
- if Assigned(OnError) then
- FOnError(Self, ERR_SOCKET, 'Could not send data');
- Disconnect;
- end;
- Exit;
- end else
- if FBuffer.SkipData(ret) then
- FBuffer.DelPacket;
- end;
- end;
- end;
- function TClSock.IsConnected: Boolean;
- begin
- Result := FClSock <> INVALID_SOCKET;
- end;
- procedure TClSock.Connect(ClearBuffer: Boolean = True);
- begin
- FResolve := False;
- if ClearBuffer then FBuffer.Clear;
- if not TestResolve(FIp) then
- begin
- if WSAAsyncGetHostByName(FWndHandle, WSA_RESOLVE_COMPLETE, PChar(FIp), @FHostIp, SizeOf(FHostIp)) = 0 then
- begin
- DoClose;
- if Assigned(OnError) then
- FOnError(Self, ERR_SOCKET, 'Cannot init async. resolving');
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- Exit;
- end;
- end else
- begin
- InitConnect(inet_addr(PChar(FIp)));
- end;
- end;
- procedure TClSock.Resolve;
- begin
- FBuffer.Clear;
- if not TestResolve(FIp) then
- begin
- FResolve := True;
- if WSAAsyncGetHostByName(FWndHandle, WSA_RESOLVE_COMPLETE, PChar(FIp), @FHostIp, SizeOf(FHostIp)) = 0 then
- begin
- DoClose;
- if Assigned(OnError) then
- FOnError(Self, ERR_SOCKET, 'Cannot init async. resolving');
- if Assigned(OnResolveFailed) then
- FOnFailed(Self);
- end;
- end else
- begin
- FResolve := False;
- if Assigned(OnResolve) then
- FOnResolve(Self, FIp);
- end;
- end;
- procedure TClSock.DoClose;
- begin
- if FClSock <> INVALID_SOCKET then
- begin
- closesocket(FClSock);
- FClSock := INVALID_SOCKET;
- end;
- end;
- procedure TClSock.Disconnect;
- var
- OldSock: TSocket;
- begin
- OldSock := FClSock;
- DoClose;
- if OldSock <> INVALID_SOCKET then
- if Assigned(OnDisconnect) then
- FOnDisconnect(Self);
- end;
- procedure TClSock.SendData(var Buf; BufLen: LongWord);
- begin
- if Assigned(OnPktParse) then
- FOnPktParse(Self, @Buf, BufLen);
- FBuffer.AddPacket(@Buf, BufLen);
- ProcessBuffer;
- end;
- procedure TClSock.SendStr(const Value: String);
- begin
- SendData(PChar(Value)^, Length(Value));
- end;
- function GetLocalIP: LongInt;
- type
- PaPInAddr = ^TaPInAddr;
- TaPInAddr = array[0..$FFFE] of PInAddr;
- var
- phe: PHostEnt;
- pptr: PaPInAddr;
- Buffer: array[0..63] of Char;
- I: Integer;
- begin
- Result := -1;
- GetHostName(Buffer, SizeOf(Buffer));
- phe := GetHostByName(buffer);
- if phe = nil then Exit;
- pptr := PaPInAddr(Phe^.h_addr_list);
- I := 0;
- while pptr^[I] <> nil do
- begin
- Result := pptr^[I]^.S_addr;
- Inc(I);
- end;
- end;
- function FindBindPort: Word;
- var
- i: Word;
- srv_address: sockaddr_in;
- sock: TSocket;
- begin
- Result := 0;
- sock := socket(AF_INET, SOCK_STREAM, 0);
- if sock = INVALID_SOCKET then
- Exit;
- srv_address.sin_family := AF_INET;
- srv_address.sin_addr.s_addr := INADDR_ANY;
- for i := 3000 to 50000 do
- begin
- srv_address.sin_port := htons(i);
- if bind(sock, srv_address, SizeOf(srv_address)) <> SOCKET_ERROR then
- begin
- closesocket(sock);
- Result := i;
- Exit;
- end;
- end;
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2}
- constructor TProxySock.Create;
- begin
- inherited Create;
- //Socket for working with TCP connections
- FSrcLen := 0;
- {$IFNDEF REMOVEHTTP}
- FCurLen := 0;
- FLen := 0;
- FICQSEQ := 0;
- FICQRecv := TClSock.Create;
- FICQRecv.OnConnect := OnHTTPRecvSockConnect;
- FICQRecv.OnRecieve := OnSockRecv;
- {$ENDIF}
- FSock := TClSock.Create;
- FSock.OnRecieve := OnSockRecv;
- FSock.OnDisconnect := OnSockDisconnect;
- FSock.OnConnectError := OnSockConnectError;
- FSock.OnPktParse := OnPktParse;
- FSock.OnConnect := OnSockConnect;
- FSock.OnResolve := OnSockResolve;
- FSock.OnResolveFailed := OnSockResolveFailed;
- FSock.OnError := OnSockError;
- end;
- {*** DESTRUCTOR ***}
- destructor TProxySock.Destroy;
- begin
- FSock.OnRecieve := nil; //. .
- FSock.OnDisconnect := nil; //. .
- FSock.OnConnectError := nil; //. DO NOT USE NOTIFICATIONS WHILE DESTROYING .
- FSock.OnPktParse := nil; //. THE OBJECT, CAUSES ACCESS VIOLATIONS .
- FSock.OnConnect := nil; //. .
- FSock.OnResolve := nil; //.
- FSock.OnError := nil;
- FSock.Free;
- {$IFNDEF REMOVEHTTP}
- FICQRecv.OnError := nil;
- FICQRecv.OnDisconnect := nil;
- FICQRecv.Free;
- {$ENDIF}
- inherited;
- end;
- {Connect procedure. Use it to connect to the remote server.}
- procedure TProxySock.Connect;
- begin
- if (ProxyType = P_SOCKS4) or (ProxyType = P_SOCKS5) {$IFNDEF REMOVEHTTP} or (ProxyType = P_HTTP) {$ENDIF} then
- begin
- {$IFNDEF REMOVEHTTP}
- FICQRecv.Disconnect;
- {$ENDIF}
- FSock.Disconnect;
- FSock.OnPktParse := nil; //Do not dump proxy data
- if not FResolve then
- begin
- FSock.IP := Host;
- FSock.Resolve;
- Exit;
- end;
- FSock.IP := ProxyHost;
- FSock.DestPort := ProxyPort;
- FSock.Connect;
- end else
- begin
- FSock.IP := Host;
- FSock.DestPort := Port;
- FSock.Connect;
- end;
- end;
- {Force socket disconnection.}
- procedure TProxySock.Disconnect;
- begin
- FSock.Disconnect;
- {$IFNDEF REMOVEHTTP}
- FICQRecv.Disconnect;
- {$ENDIF}
- end;
- {Called when socket cannot connect to remote host.}
- procedure TProxySock.OnSockConnectError(Sender: TObject);
- begin
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- end;
- {Called when closed connection.}
- procedure TProxySock.OnSockDisconnect(Sender: TObject);
- begin
- if Assigned(OnDisconnect) then
- FOnDisconnect(Self);
- end;
- procedure TProxySock.OnSockError(Sender: TObject; ErrorType: TErrorType; ErrorMsg: String);
- begin
- if Assigned(OnError) then
- FOnError(Self, ErrorType, ErrorMsg);
- end;
- function TProxySock.GetWndHandle: THandle;
- begin
- Result := FSock.WndHandle;
- end;
- {$IFNDEF REMOVEHTTP}
- procedure TProxySock.InitRecvConnection;
- begin
- FICQRecv.IP := ProxyHost;
- FICQRecv.DestPort := ProxyPort;
- FICQRecv.Disconnect;
- FICQRecv.Connect;
- end;
- procedure TProxySock.OnHTTPRecvSockConnect(Sender: TObject);
- begin
- FICQRecv.SendStr(CreateHTTP_RECV(FICQPIP, FICQSID));
- end;
- procedure TProxySock.OnHTTPDataSent(Sender: TObject);
- begin
- //FSock.Disconnect;
- end;
- {$ENDIF}
- {Called when resolving of Host has been complete.}
- procedure TProxySock.OnSockResolve(Sender: TObject; Addr: String);
- begin
- if FProxyType = P_NONE then Exit;
- Host := Addr;
- FSock.IP := ProxyHost;
- FSock.DestPort := ProxyPort;
- FSock.Connect;
- end;
- {Called when resolving failed.}
- procedure TProxySock.OnSockResolveFailed(Sender: TObject);
- begin
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- end;
- {Called after our socket connected to server.}
- procedure TProxySock.OnSockConnect(Sender: TObject);
- var
- buf: array[0..255] of Byte;
- begin
- if ProxyType = P_NONE then //Do nothing if we are not using proxies
- begin
- if Assigned(OnConnectProc) then
- FOnConnectProc(Self);
- Exit
- end
- else if ProxyType = P_SOCKS4 then
- begin
- buf[0] := 4; //Socks4
- buf[1] := 1; //Code: 1 - Connect
- PWord(Ptr(LongWord(@Buf) + 2))^ := htons(Port); //Port
- PDWord(Ptr(LongWord(@Buf) + 4))^ := inet_addr(PChar(Host)); //Host
- if ProxyAuth then //Add some packet specified data when using proxy authentication
- begin
- if Length(ProxyUserID) > 0 then //Test if ProxyUserID string is not nil
- Move(PChar(ProxyUserID)^, buf[8], Length(ProxyUserID)); //If it's not then add it to packet
- buf[8 + Length(ProxyUserID) + 1] := 0; //Always present NULL termination byte
- end else
- buf[9] := 0; //Always present NULL termination byte
- FSock.SendData(buf, 8 + Length(ProxyUserID) + 1);
- end
- else if ProxyType = P_SOCKS5 then
- begin
- FSocks := 0; //Socks authorization progress
- buf[0] := 5; //Socks5
- buf[1] := 1; //Number of methods
- if ProxyAuth then //Choose auth method
- buf[2] := 2 //Use authentication
- else
- buf[2] := 0; //Plain connect
- FSock.SendData(buf, 3); //Send SOCKS5 initialization packet
- end
- {$IFNDEF REMOVEHTTP}
- else if ProxyType = P_HTTP then
- FSock.SendStr(CreateHTTP_INIT);
- {$ENDIF}
- end;
- {$IFNDEF REMOVEHTTP}
- procedure TProxySock.SendHTTPData(Buffer: Pointer; BufLen: LongWord);
- var
- buf: TRawPkt;
- begin
- if BufLen = 0 then Exit;
- Inc(FICQSeq);
- PktInitRaw(@buf);
- PktStr(@buf, CreateHTTP_Header('POST', 'http://' + FICQPIP + '/data?sid=' + FICQSID + '&seq=' + IntToStr(FICQSeq), FICQPIP, BufLen));
- PktAddArrBuf(@buf, Buffer, BufLen);
- FSock.Ip := ProxyHost;
- FSock.DestPort := ProxyPort;
- if not FSock.Connected then
- FSock.Connect(False);
- FSock.SendData(buf, buf.Len);
- end;
- procedure TProxySock.HandleHTTPDataPak(Buffer: Pointer; BufLen: LongWord);
- var
- pkt: TRawPkt;
- ptype: Word;
- sw: LongWord;
- begin
- Move(Buffer^, pkt.Data, BufLen);
- pkt.Len := 0;
- GetInt(@pkt, 2); //Version
- ptype := GetInt(@pkt, 2);
- Inc(pkt.Len, 6);
- case ptype of
- 2 {HELLO REPLY}:
- begin
- sw := GetInt(@pkt, 4); FICQSid := IntToHex(sw, 8);
- sw := GetInt(@pkt, 4); FICQSid := FICQSid + IntToHex(sw, 8);
- sw := GetInt(@pkt, 4); FICQSid := FICQSid + IntToHex(sw, 8);
- sw := GetInt(@pkt, 4); FICQSid := FICQSid + IntToHex(sw, 8);
- FICQPIP := GetWStr(@pkt);
- FICQPPort := GetLInt(@pkt, 2);
- CreateHTTP_LOGIN(@pkt, Host, Port);
- SendHTTPData(@pkt, pkt.Len);
- end;
- 5 {FLAP PACKETS}:
- OnReceive(Ptr(LongWord(@pkt.Data) + pkt.Len + 2), BufLen - pkt.Len - 2);
- end;
- end;
- procedure TProxySock.HandleHTTPData(Buffer: Pointer; BufLen: LongWord);
- function GetHTTPStatus(List: TStringList): String;
- var
- i, c: Word;
- S: String;
- begin
- if List.Count < 1 then Exit;
- S := List.Strings[0]; c := 0;
- for i := 1 to Length(S) do
- if c = 1 then
- Result := Result + S[i]
- else
- if S[i] = ' ' then Inc(c);
- end;
- function GetHTTPLength(List: TStringList): Integer;
- var
- i: Word;
- begin
- Result := 0;
- if List.Count < 1 then Exit;
- for i := 0 to List.Count - 1 do
- if Copy(List.Strings[i], 0, 16) = 'Content-Length: ' then
- begin
- Result := StrToInt(Copy(List.Strings[i], 16, $FF));
- Exit;
- end;
- end;
- {$WARNINGS OFF}
- procedure HandleICQPakHTTP(Buffer: Pointer; BufLen: LongWord);
- var
- Len: Word;
- Buf: TRawPkt;
- l: LongWord;
- begin
- l := 0;
- if BufLen > $FFFF then Exit;
- while True do
- begin
- if l = BufLen then Break;
- Len := Swap16(PWord(Buffer)^);
- if (Len > 8192) or (Len < 12) then Break;
- Move(Ptr(LongWord(Buffer) + 2)^, Buf, Len);
- Inc(l, Len + 2);
- Buffer := Ptr(LongWord(Buffer) + Len + 2);
- {Handle ICQ Pak packet}
- HandleHTTPDataPak(@Buf, Len);
- //LogText('proto.txt', DumpPacket(@Buf, Len));
- end;
- end;
- {$WARNINGS ON}
- var
- i: LongWord;
- List: TStringList;
- l: LongWord;
- s: String;
- begin
- if BufLen < 1 then Exit;
- for i := 0 to BufLen - 1 do
- begin
- FBuf[FCurLen] := PByte(LongWord(Buffer) + i)^;
- Inc(FCurLen);
- if flen = 0 then
- if FCurLen > 3 then
- if Copy(PChar(@FBuf), FCurLen - 3, 4) = #13#10#13#10 then
- begin
- FCurLen := 0;
- List := TStringList.Create;
- List.Text := PChar(@FBuf);
- s := GetHTTPStatus(List);
- flen := GetHTTPLength(List);
- List.Free;
- if s <> '200 OK' then
- begin
- if Assigned(OnError) then
- FOnError(Self, ERR_PROTOCOL, 'Http proxy returned invalid status: ' + s);
- FSock.Disconnect;
- FICQRecv.Disconnect;
- Exit;
- end;
- end;
- if (FCurLen = flen) and (FCurLen <> 0) then
- begin
- l := FCurLen; flen := 0; FCurLen := 0; {using l, avoiding AVs}
- HandleICQPakHTTP(@FBuf, l);
- InitRecvConnection;
- {send HTTP_RECV}
- //FSock.SendStr(CreateHTTP_RECV(FICQPIP, FICQSID))
- end;
- end;
- end;
- {$ENDIF}
- {Called when something received on socket.}
- procedure TProxySock.OnSockRecv(Sender: TObject; Socket: TSocket; Buffer: Pointer; BufLen: LongWord);
- var
- i: Word;
- UserLen, PassLen: Word;
- procedure DoSocks5Connect;
- var
- len: Word;
- buf: array[0..255] of Byte;
- begin
- if not UseProxyResolve then //Socks5 supports on-server-resolving
- len := 4
- else
- len := Length(Host) + 1;
- buf[0] := 5; //Socks5
- buf[1] := 1; //Command: connect
- buf[2] := 0; //Reserved
- if UseProxyResolve then
- begin
- buf[3] := 3;
- buf[4] := len - 1;
- Move(PChar(Host)^, buf[5], len - 1);
- end else
- begin
- buf[3] := 1;
- PDWord(LongWord(@buf) + 4)^ := inet_addr(PChar(Host));
- end;
- PWord(LongWord(@buf) + 4 + Len)^ := htons(Port);
- FSock.SendData(buf, 6 + Len);
- end;
- begin
- if BufLen = 0 then Exit;
- if ProxyType = P_SOCKS4 then
- begin
- for i := 0 to BufLen - 1 do
- begin
- FSrcBuf[FSrcLen] := PByte(LongWord(Buffer) + i)^;
- Inc(FSrcLen);
- if FSrcLen = 8 then
- begin
- FProxyType := P_NONE; //After we connected to proxy we work as usual
- Dec(BufLen, i);
- FSrcLen := 0;
- if PByte(Ptr(LongWord(Buffer) + 1))^ <> 90 then
- begin
- if Assigned(OnError) then
- FOnError(Self, ERR_PROXY, 'SOCKS4 server cannot connect to remote server');
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- Exit;
- end;
- FSock.OnPktParse := OnPktParse;
- if Assigned(OnConnectProc) then
- FOnConnectProc(Self);
- if i < BufLen - 1 then
- OnSockRecv(Sender, Socket, Ptr(LongWord(Buffer) + i), BufLen); //Continue handling of remaining data
- end;
- end;
- Exit;
- end else
- if ProxyType = P_SOCKS5 then
- begin
- for i := 0 to BufLen - 1 do
- begin
- FSrcBuf[FSrcLen] := PByte(LongWord(Buffer) + i)^;
- Inc(FSrcLen);
- case FSocks of
- 0:
- begin
- if FSrcLen = 2 then
- begin
- if FSrcBuf[1] = $ff then
- begin
- if Assigned(OnError) then
- FOnError(Self, ERR_PROXY, 'Auth methods are not supported by SOCKS5 server');
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- Exit;
- end;
- FSrcLen := 0;
- if FSrcBuf[1] = 2 then
- begin
- UserLen := Length(ProxyUserID);
- PassLen := Length(ProxyPass);
- FSrcBuf[0] := 1;
- FSrcBuf[1] := UserLen;
- Move(PChar(ProxyUserID)^, Ptr(LongWord(@FSrcBuf) + 2)^, UserLen);
- FSrcBuf[UserLen + 2] := PassLen;
- Move(PChar(ProxyPass)^, Ptr(LongWord(@FSrcBuf) + 3 + UserLen)^, UserLen);
- FSock.SendData(FSrcBuf, 3 + UserLen + PassLen);
- Inc(FSocks);
- end else
- begin
- Inc(FSocks, 2);
- DoSocks5Connect;
- end;
- end;
- end;
- 1:
- begin
- if FSrcLen = 2 then
- begin
- if FSrcBuf[1] <> 0 then
- begin
- if Assigned(OnError) then
- FOnError(Self, ERR_PROXY, 'SOCKS5 server cannot authenticate us');
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- Exit;
- end;
- FSrcLen := 0;
- Inc(FSocks);
- DoSocks5Connect;
- end;
- end;
- 2:
- begin
- if FSrcLen = 10 then
- begin
- if (FSrcBuf[0] <> 5) or (FSrcBuf[1] <> 0) then
- begin
- if Assigned(OnError) then
- FOnError(Self, ERR_PROXY, 'SOCKS5 server cannot connect to remote server');
- if Assigned(OnConnectError) then
- FOnConnectError(Self);
- Exit;
- end;
- FSrcLen := 0;
- ProxyType := P_NONE;
- FSock.OnPktParse := OnPktParse;
- if Assigned(OnConnectProc) then
- FOnConnectProc(Self);
- if i < BufLen - 1 then
- OnSockRecv(Sender, Socket, Ptr(LongWord(Buffer) + i), BufLen); //Continue handling of remaining data
- end;
- end;
- end;
- end;
- Exit;
- end; {$IFNDEF REMOVEHTTP} else
- if ProxyType = P_HTTP then
- begin
- HandleHTTPData(Buffer, BufLen);
- InitRecvConnection;
- Exit;
- end;{$ENDIF}
- OnReceive(Buffer, BufLen);
- end;
- {Called when some data has been sent through socket.}
- procedure TProxySock.OnPktParse(Sender: TObject; Buffer: Pointer; BufLen: LongWord);
- begin
- if Assigned(OnPktParseA) then
- FOnPktParse(Sender, Buffer, BufLen, False);
- end;
- {Sending data throgh socket.}
- procedure TProxySock.SendData(var Buf; BufLen: LongWord);
- {$IFNDEF REMOVEHTTP}
- var
- pkt: TRawPkt;
- {$ENDIF}
- begin
- {$IFNDEF REMOVEHTTP}
- if FProxyType <> P_HTTP then
- FSock.SendData(Buf, BufLen)
- else begin
- if Assigned(OnPktParseA) then
- FOnPktParse(Self, @Buf, BufLen, False);
- CreateHTTP_DATA(@pkt, $0005, @Buf, BufLen);
- SendHTTPData(@pkt, pkt.Len);
- end;
- {$ELSE}
- FSock.SendData(Buf, BufLen)
- {$ENDIF}
- end;
- {Forward handlers.}
- procedure TProxySock.OnReceive;
- begin
- if Assigned(OnReceiveProc) then
- FOnRecv(Self, FSock.FClSock, Buffer, BufLen);
- end;
- function TMySock.GetClientSocket: TSocket;
- begin
- Result := FSock.FClSock;
- end;
- procedure TMySock.SetClientSocket(Socket: TSocket);
- begin
- FSock.FClSock := Socket;
- end;
- function TMySock.IsConnected: Boolean;
- begin
- Result := FSock.IsConnected;
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=}
- constructor TSrvSock.Create;
- begin
- inherited;
- FWndHandle := AllocateHwnd(OnSockMsg);
- FSrvSock := INVALID_SOCKET;
- FPort := 0;
- end;
- destructor TSrvSock.Destroy;
- begin
- StopServer;
- DeallocateHwnd(FWndHandle);
- inherited;
- end;
- procedure TSrvSock.OnSockMsg(var Msg: TMessage);
- var
- rc: Integer;
- acc_sin_len: Integer;
- acc_sin: sockaddr_in;
- FClSock: TSocket;
- FCl: TMySock;
- begin
- case Msg.Msg of
- WSA_ACCEPT:
- begin
- if WSAGETSELECTERROR(Msg.lParam) <> 0 then
- begin
- MessageBox(0, 'accept() Error', 'Error', MB_OK);
- //WSAAsyncSelect(FSrvSock, FWndHandle, 0, 0);
- Exit;
- end;
- //Size of acc_sin
- acc_sin_len := SizeOf(acc_sin);
- //Allow connection
- FClSock := accept(FSrvSock, @acc_sin, @acc_sin_len);
- if FClSock = INVALID_SOCKET then
- begin
- MessageBox(0, 'accept() Error, invalid socket', 'Error', MB_OK);
- Exit;
- end;
- FCl := TMySock.Create;
- FCl.ClientSocket := FClSock;
- //Allow network notifies in client socket
- rc := WSAAsyncSelect(FClSock, FCl.WndHandle, WSA_NETEVENT,
- FD_READ or FD_CLOSE or FD_WRITE);
- if rc > 0 then
- begin
- closesocket(FClSock);
- MessageBox(0, 'WSAAsyncSelect Error', 'Error', MB_OK);
- FCl.Free;
- Exit;
- end;
- if Assigned(OnClientConnected) then
- FOnClientConnected(Self, FCl);
- end else
- Msg.Result := DefWindowProc(FWndHandle, Msg.Msg, Msg.WParam, Msg.LParam);
- end;
- end;
- function TSrvSock.StartServer(Port: Word): Boolean;
- var
- srv_address: sockaddr_in;
- rc: Integer;
- begin
- Result := False;
- FPort := 0;
- //Creating server socket
- FSrvSock := socket(AF_INET, SOCK_STREAM, 0);
- if FSrvSock = INVALID_SOCKET then
- begin
- MessageBox(0, 'Could not create server socket()', 'Error', MB_OK);
- Exit;
- end;
- srv_address.sin_family := AF_INET;
- srv_address.sin_addr.s_addr := INADDR_ANY; //Accept connection from all addresses
- srv_address.sin_port := htons(Port); //Set local port
- //Binding a port
- if bind(FSrvSock, srv_address, SizeOf(srv_address)) = SOCKET_ERROR then
- begin
- //Closing socket on error
- closesocket(FSrvSock);
- MessageBox(0, 'Could not bind server', 'Error', MB_OK);
- Exit;
- end;
- //Setting socket in listen status
- if listen(FSrvSock, 5) = SOCKET_ERROR then
- begin
- closesocket(FSrvSock);
- MessageBox(0, 'listen() Error', 'Error', MB_OK);
- Exit;
- end;
- rc := WSAAsyncSelect(FSrvSock, FWndHandle, WSA_ACCEPT, FD_ACCEPT);
- if rc > 0 then
- begin
- closesocket(FSrvSock);
- MessageBox(0, 'WSAAsyncSelect Error', 'Error', MB_OK);
- Exit;
- end;
- Result := True;
- FPort := Port;
- end;
- function TSrvSock.StopServer: Boolean;
- begin
- Result := False;
- if FSrvSock <> INVALID_SOCKET then
- begin
- //Removing receiveing of all notifications
- WSAAsyncSelect(FSrvSock, FWndHandle, 0, 0);
- //If socket was created then close it
- closesocket(FSrvSock);
- FSrvSock := INVALID_SOCKET;
- Result := True;
- end;
- end;
- initialization
- begin
- InitMySocket(WSA);
- {$IFNDEF USE_FORMS}
- InstBlockList := nil;
- InstFreeList := nil;
- {$ENDIF}
- end;
- finalization
- begin
- FinalMySocket;
- end;
- end.