⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 awwnsock.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 4 页
字号:
(***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is TurboPower Async Professional
 *
 * The Initial Developer of the Original Code is
 * TurboPower Software
 *
 * Portions created by the Initial Developer are Copyright (C) 1991-2002
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** *)

{*********************************************************}
{*                   AWWNSOCK.PAS 4.06                   *}
{*********************************************************}
{* Winsock device layer and dispatcher                   *}
{*********************************************************}

{Global defines potentially affecting this unit}
{$I AWDEFINE.INC}

{Options required for this unit}
{$X+,F+,K+,B-,T-}
{$IFDEF Win32}
 {$J+}
{$ENDIF}

unit AwWnsock;
  { -Device layer for Winsock API }

interface

uses
  WinTypes,
  WinProcs,
  Classes,
  SysUtils,
  AdWUtil,
  AdSocket,
  OoMisc,
  awUser;

const
  DefAsyncStyles = FD_READ or FD_WRITE or FD_ACCEPT or FD_CONNECT or FD_CLOSE;
  DefWsTerminal = 'vt100';
  DefOptSupga  = True;
  DefOptEcho   = True;

  { Telnet Commands }
  TELNET_IAC   = #255;  { Interpret as Command }
  TELNET_DONT  = #254;  { Stop performing, or not expecting him to perform }
  TELNET_DO    = #253;  { Perform, or expect him to perform }
  TELNET_WONT  = #252;  { Refusal to perform }
  TELNET_WILL  = #251;  { Desire to perform }
  TELNET_SB    = #250;  { What follow is sub-negotiation of indicated option }
  TELNET_GA    = #249;  { Go ahead signal }
  TELNET_EL    = #248;  { Erase Line function }
  TELNET_EC    = #247;  { Erase Character function }
  TELNET_AYT   = #246;  { Are You There function }
  TELNET_AO    = #245;  { Abort Output function }
  TELNET_IP    = #244;  { Interrupt Process function }
  TELNET_BRK   = #243;  { NVT break character }
  TELNET_DM    = #242;  { Data stream portion of a Synch (DATAMARK) }
  TELNET_NOP   = #241;  { No operation }
  TELNET_SE    = #240;  { End of sub-negotiation parameters }
  TELNET_EOR   = #239;  { End of record }
  TELNET_ABORT = #238;  { Abort process }
  TELNET_SUSP  = #237;  { Suspend current process }
  TELNET_EOF   = #236;  { End of file }

  TELNET_NULL  = #0;
  TELNET_LF    = #10;
  TELNET_CR    = #13;                                               

  { Telnet Options }
  TELNETOPT_BINARY = #0;     { Transmit binary }
  TELNETOPT_ECHO   = #1;     { Echo mode }
  TELNETOPT_SUPGA  = #3;     { Suppress Go-Ahead }
  TELNETOPT_TERM   = #24;    { Terminal Type }
  TELNETOPT_SPEED  = #32;    { Terminal Speed }

type
  PServerClientRec = ^TServerClientRec;
  TServerClientRec = record
    ServerSocket : TSocket;
    ClientSocket : TSocket;
  end;

  TWsConnectionState = (wcsInit, wcsConnected);

  TTelnetOpt = (tnoFalse, tnoNegotiating, tnoTrue);                

  TApdWinsockDispatcher = class;

  TWsConnection = class(TComponent)
  private
    FSimBuf : Cardinal;                                               
    FCommSocket : TSocket;        { Socket which the IO goes through }
    FDispatcher : TApdWinsockDispatcher; { Pointer to the associated ComRec }
    FConnectionState : TWsConnectionState;
    FInBuf : PChar;               { Pointer to input buffer }
    FInBufEnd : PChar;            { Sentinel at end of input buffer }
    FInBufFull : Boolean;         { Flag set when buffer is full }
    FInSize : Cardinal;           { Size of input buffer }
    FInStart : PChar;             { Pointer to first character of data }
    FInCursor : PChar;            { Pointer to first char to be telnet checked }
    FInEnd : PChar;               { Pointer to first free character in buffer }
    FIsClient : Boolean;          { True if socket is a client -- false if server }
    FIsTelnet : Boolean;          { True if telnet parsing should be done }
    FOutBuf : PChar;              { Pointer to output buffer }
    FOutBufEnd : PChar;           { Sentinel at end of output buffer }
    FOutBufFull : Boolean;        { Flag set when buffer is full }
    FOutSize : Cardinal;          { Size of output buffer }
    FOutStart : PChar;            { Pointer to first character of data }
    FOutEnd : PChar;              { Pointer to first free character in buffer }
    FSocketHandle : TSocket;      { Socket that is associated with the comport }
    FOptBinary : TTelnetOpt;
    FOptSupga  : TTelnetOpt;
    FOptEcho   : TTelnetOpt;
  protected
    function GetConnected : Boolean;
    function GetInChars : Cardinal;
    function GetOutChars : Cardinal;
    procedure SetConnectionState(Value : TWsConnectionState);
  public
    constructor CreateInit(AOwner: TComponent; InSize, OutSize : Cardinal); virtual;
    destructor Destroy; override;
    function FindIAC(Start : PChar; Size : Cardinal) : PChar;
    procedure FlushInBuffer;
    procedure FlushOutBuffer;
    function HandleCommand(Command, Option : Char) : Boolean;         
    function ProcessCommands(Dest : PChar; Size : Cardinal) : Integer;
    function ReadBuf(var Buf; Size : Integer) : Integer;
    procedure SendDo(Option: Char);
    procedure SendDont(Option: Char);
    procedure SendWill(Option: Char);
    procedure SendWont(Option: Char);
    procedure SendTerminal;
    function Shutdown : Integer;
    function WriteBuf(var Buf; Size : Integer) : Integer;
    property CommSocket : TSocket read FCommSocket;
    property Connected : Boolean read GetConnected;
    property ConnectionState : TWsConnectionState
      read FConnectionState write SetConnectionState;
    property InChars : Cardinal read GetInChars;
    property InSize : Cardinal read FInSize;
    property IsClient : Boolean read FIsClient write FIsClient;
    property IsTelnet : Boolean read FIsTelnet write FIsTelnet;
    property OutChars : Cardinal read GetOutChars;
    property OutSize : Cardinal read FOutSize;
    property SocketHandle : TSocket read FSocketHandle;
  end;


  TApdDeviceSocket = class(TApdSocket)
  private
    FWsTerminal : string;
    {$IFDEF Win32}
    SockSection : TRTLCriticalSection;                               
    {$ENDIF}
  protected
    function DoDispMessage(Socket : TSocket; Event : Cardinal; LP : LongInt) : LongInt;
    function DoWsMessage(Socket : TSocket; Event : Cardinal; LP : LongInt) : LongInt;
    procedure DoAccept(Socket : TSocket); override;
    procedure DoConnect(Socket : TSocket); override;
    procedure DoDisconnect(Socket : TSocket); override;
    procedure DoError(Socket : TSocket; ErrCode : Integer); override;
    procedure DoRead(Socket : TSocket); override;
    procedure DoWrite(Socket : TSocket); override;
    function TweakSocket(Socket : TSocket) : TSocket;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    {$IFDEF Win32}
    procedure LockList;                                               
    procedure UnLockList;                                            
    {$ENDIF}
    function FindConnection(Socket : TSocket) : TWsConnection;
    property WsTerminal : string read FWsTerminal write FWsTerminal;
  end;

  TApdWinsockDispatcher = class(TApdBaseDispatcher)
  private
    InDispatcher : Boolean;
    WsSockAddr : TSockAddrIn;
    WsHostAddr : TSockAddrIn;
    WsIsClient : Boolean;
    WsIsTelnet : Boolean;
  protected
    function EscapeComFunction(Func : Integer) : LongInt; override;
    function FlushCom(Queue : Integer) : Integer; override;
    function GetComError(var Stat : TComStat) : Integer; override;
    function GetComEventMask(EvtMask : Integer) : Cardinal; override;
    function GetComState(var DCB: TDCB): Integer; override;
    {$IFNDEF Win32}
    function SetComEventMask(EvtMask : Cardinal) : PWord; override;
    {$ENDIF}
    function SetComState(var DCB : TDCB) : Integer; override;
    procedure StartDispatcher; override;
    procedure StopDispatcher; override;
    function ReadCom(Buf : PChar; Size: Integer) : Integer; override;
    function WriteCom(Buf : PChar; Size: Integer) : Integer; override;
    {$IFNDEF Win32}
    procedure SetMsrShadow(OnOff : Boolean); override;
    {$ENDIF}
    function SetupCom(InSize, OutSize : Integer) : Boolean; override;
    {$IFDEF Win32}
    function WaitComEvent(var EvtMask : DWORD;
      lpOverlapped : POverlapped) : Boolean; override;
    {$ENDIF}
    function Dispatcher(Msg : Cardinal;
                         wParam : Cardinal; lParam : LongInt) : Cardinal;
  public
    function CloseCom : Integer; override;
    procedure InitSocketData(LocalAddress, Address : Longint; Port : Cardinal;
      IsClient, IsTelnet : Boolean);
    function OpenCom(ComName: PChar; InQueue,
      OutQueue : Cardinal) : Integer; override;
    function ProcessCommunications : Integer; override;              
  end;

var
  ApdSocket : TApdDeviceSocket;

implementation
uses
  AdPort;

{ TWsConnection methods }

{ Create and initialize connection -- owner is assumed to be a TApdDeviceSocket }
constructor TWsConnection.CreateInit(AOwner: TComponent; InSize, OutSize : Cardinal);
begin
  inherited Create(AOwner);
  FSocketHandle := TApdDeviceSocket(Owner).CreateSocket;
  { Create input buffer, and initialize -- full flag is already False }
  GetMem(FInBuf, InSize);
  FInSize := InSize;
  FInBufEnd := FInBuf + FInSize;
  FInStart := FInBuf;
  FInEnd := FInBuf;
  FInCursor := FInBuf;
  { Create output buffer, and initialize -- full flag is already False }
  { Extra space for telnet escaping }
  GetMem(FOutBuf, OutSize + 4096);
  FOutSize := OutSize + 4096;                                    
  FOutBufEnd := FOutBuf + FOutSize;
  FOutStart := FOutBuf;
  FOutEnd := FOutBuf;
  { Other inits }
  FCommSocket := SOCKET_ERROR;
  ConnectionState := wcsInit;
end;

function TWsConnection.FindIAC(Start : PChar; Size : Cardinal) : PChar;
var
  I : Cardinal;
begin
  if FIsTelnet then begin
    Result := Start;
  end else begin
    Result := Start + Size;
    Exit;
  end;
  for I := 0 to Size do begin
    if (Result^ = TELNET_IAC) then Exit;
    if (FOptBinary = tnoFalse) and (Result^ = TELNET_CR) then Exit;  
    Result := (Start + I);
  end;
end;

{ Flush local input buffer }
procedure TWsConnection.FlushInBuffer;
begin
  FInStart := FInBuf;
  FInCursor := FInBuf;
  FInEnd := FInBuf;
  FInBufFull := False;
end;

{ Flush local output buffer }
procedure TWsConnection.FlushOutBuffer;
begin
  FOutStart := FOutBuf;
  FOutEnd := FOutBuf;
  FOutBufFull := False;
end;

{ Handle a telnet command - result is True if negotation command }
function TWsConnection.HandleCommand(Command, Option : Char) : Boolean; 
begin
  Result := True;
  case Command of
    TELNET_DONT :
    begin
      if FDispatcher.DLoggingOn then
        FDispatcher.AddDispatchEntry(dtTelnet, dstRDont, Ord(Option), nil, 0);
      case Option of
        TELNETOPT_BINARY :
        begin
          if FOptBinary <> tnoNegotiating then
            SendWont(Option);
          FOptBinary := tnoFalse;
        end;
        TELNETOPT_SUPGA  :
        begin
          if FOptSupga <> tnoNegotiating then
            SendWont(Option);
          FOptSupga := tnoFalse;
        end else begin
          SendWont(Option);
        end;
      end;
    end;
    TELNET_DO :
    begin
      if FDispatcher.DLoggingOn then
        FDispatcher.AddDispatchEntry(dtTelnet, dstRDo, Ord(Option), nil, 0);
      case Option of
        TELNETOPT_BINARY :
        begin
          if FOptBinary <> tnoNegotiating then
            SendWill(Option);
          FOptBinary := tnoTrue;
        end;
        TELNETOPT_SUPGA  :
        begin
          if FOptSupga <> tnoNegotiating then begin
            if FOptSupga = tnoTrue then begin
              SendWill(Option);
            end else begin
              SendWont(Option);
            end;
          end else begin
            FOptSupga := tnoTrue;
          end;
        end;
        TELNETOPT_TERM   :
        begin
          SendWill(Option);
        end;
        TELNETOPT_SPEED  :
        begin
          SendWont(Option);
        end;
        TELNETOPT_ECHO   :
        begin
          SendWont(Option);
        end else begin
          SendWont(Option);
        end;
      end;
    end;
    TELNET_WONT :
    begin
      if FDispatcher.DLoggingOn then
        FDispatcher.AddDispatchEntry(dtTelnet, dstRWont, Ord(Option), nil, 0);
      case Option of
        TELNETOPT_BINARY :
        begin
          if FOptBinary <> tnoNegotiating then
            SendDont(Option);
          FOptBinary := tnoFalse;
        end;
        TELNETOPT_SUPGA  :
        begin
          if FOptSupga <> tnoNegotiating then
            SendDont(Option);
          FOptSupga := tnoFalse;
        end;
        TELNETOPT_ECHO   :
        begin
          if FOptEcho <> tnoNegotiating then
            SendDont(Option);
          FOptEcho := tnoFalse;
        end else begin
          SendDont(Option);
        end;
      end;
    end;
    TELNET_WILL :
    begin
      if FDispatcher.DLoggingOn then
        FDispatcher.AddDispatchEntry(dtTelnet, dstRWill, Ord(Option), nil, 0);
      case Option of
        TELNETOPT_BINARY :
        begin
          if FOptBinary <> tnoNegotiating then
            SendDo(Option);
          FOptBinary := tnoTrue;
        end;
        TELNETOPT_SUPGA  :
        begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -