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

📄 nmudpex.pas

📁 nmudp
💻 PAS
📖 第 1 页 / 共 2 页
字号:
    end {_ try _}
  else {_ NOT if WSAStartUp($0101, MyWSADATA) = 0 then _}
    ErrorManager(WSAEWOULDBLOCK); {Handle Statrtup error}
  FLocalPort := NewLocalPort;
  Loaded;
end; {_ procedure TNMUDPEX.SetLocalPort(NewLocalPort: integer); _}


procedure TNMUDPEX.Loaded;
var
  buf: array[0..17] of char;
begin
  if not (csDesigning in ComponentState) then
    begin
      RemoteAddress2.sin_addr.S_addr := Inet_Addr(strpcopy(buf, '0.0.0.0'));
      RemoteAddress2.sin_family := AF_INET; {Family = Internet address}
      RemoteAddress2.sin_port := htons(FLocalPort); {Set port to given port}
      wait_flag := FALSE; {Set flag to wait}
      {Bind Socket to given address}
      WinSock.bind(ThisSocket, RemoteAddress2, SizeOf(RemoteAddress2));
      {Direct reply message to WM_WAITFORRESPONSE handler}
      WSAAsyncselect(ThisSocket, FSocketWindow, WM_ASYNCHRONOUSPROCESS, FD_READ);
    end; {_ if not (csDesigning in ComponentState) then _}
end; {_ procedure TNMUDPEX.Loaded; _}

{*******************************************************************************************
Resolve IP Address of Remote Host
********************************************************************************************}

procedure TNMUDPEX.ResolveRemoteHost;
var
  BUF: array[0..127] of char;
  CTry: integer;
  Handled: boolean;
begin
  remoteaddress.sin_addr.S_addr := Inet_Addr(strpcopy(buf, FRemoteHost));
  if remoteaddress.sin_addr.S_addr = SOCKET_ERROR then
      {If given name not an IP address already}
    begin
      CTry := 0;
      repeat
        Wait_Flag := FALSE; {Reset flag indicating wait over}
         {Resolve IP address}
        wsaasyncgethostbyname(FSocketWindow, WM_ASYNCHRONOUSPROCESS, Buf, PChar(remotehostS), MAXGETHOSTSTRUCT);
        repeat
          Wait;
        until Wait_Flag or Canceled; {Till host name resolved, Timed out or cancelled}
         {Handle errors}
        if Canceled then
          raise UDPSockError.create(Cons_Msg_Lkp);
        if Succeed = FALSE then
          begin
            if CTry < 1 then
              begin
                CTry := CTry + 1;
                Handled := FALSE;
                if assigned(FOnInvalidHost) then FOnInvalidHost(Handled);
                if not handled then UDPSockError.create(Cons_Msg_Lkp);
              end {_ if CTry < 1 then _}
            else {_ NOT if CTry < 1 then _}  raise UDPSockError.create(Cons_Msg_Lkp);
          end {_ if Succeed = FALSE then _}
        else {_ NOT if Succeed = FALSE then _}
            {Fill up remote host information with retreived results}
          with RemoteAddress.sin_addr.S_un_b do
            begin
              s_b1 := remotehostS.h_addr_list^[0];
              s_b2 := remotehostS.h_addr_list^[1];
              s_b3 := remotehostS.h_addr_list^[2];
              s_b4 := remotehostS.h_addr_list^[3];
            end; {_ with RemoteAddress.sin_addr.S_un_b do _}
      until Succeed = true;
    end; {_ if remoteaddress.sin_addr.S_addr = SOCKET_ERROR then _}
end; {_ procedure TNMUDPEX.ResolveRemoteHost; _}

procedure TNMUDPEX.SendStream(DataStream: TStream);
var Ctry, i: integer;
  BUf: array[0..DataPackSize] of char;                //////lsyx
  Handled: boolean;
begin
  CTry := 0;
  while DataStream.size = 0 do
    if CTry > 0 then raise Exception.create(Cons_Msg_InvStrm)
    else {_ NOT if CTry > 0 then raise Exception.create(Cons_Msg_InvStrm) _}
      if not assigned(FOnStreamInvalid) then raise Exception.create(Cons_Msg_InvStrm)
      else {_ NOT if not assigned(FOnStreamInvalid) then raise Exception.create(Cons_Msg_InvStrm) _}
        begin
          Handled := FALSE;
          FOnStreamInvalid(Handled, DataStream);
          if not Handled then raise Exception.create(Cons_Msg_InvStrm)
          else {_ NOT if not Handled then raise Exception.create(Cons_Msg_InvStrm) _}  CTry := CTry + 1;
        end; {_ NOT if not assigned(FOnStreamInvalid) then raise Exception.create(Cons_Msg_InvStrm) _}
  Canceled := FALSE; {Turn Canceled off}
  ResolveRemoteHost; {Resolve the IP address of remote host}
  if RemoteAddress.sin_addr.S_addr = 0 then
    raise UDPSockError.create(Cons_Err_Addr); {If Resolving failed raise exception}
  StatusMessage(Status_Basic, Cons_Msg_Data); {Inform status}
  RemoteAddress.sin_family := AF_INET; {Make connected true}
{$R-}
  RemoteAddress.sin_port := htons(FRemotePort); {If no proxy get port from Port property}
{$R+}
  i := SizeOf(RemoteAddress); {i := size of remoteaddress structure}
   {Connect to remote host}
  DataStream.position := 0;
  DataStream.ReadBuffer(Buf, DataStream.size);
  WinSock.SendTo(ThisSocket, Buf, DataStream.size, 0, RemoteAddress, i);
  if assigned(FOnDataSend) then FOnDataSend(self);
end; {_ procedure TNMUDPEX.SendStream(DataStream: TStream); _}

procedure TNMUDPEX.SendBuffer(Buff: array of char; length: integer);
var Ctry, i: integer;
  Handled: boolean;
begin
  CTry := 0;
  while length = 0 do
    if CTry > 0 then raise Exception.create(Cons_Err_Buffer)
    else {_ NOT if CTry > 0 then raise Exception.create(Cons_Err_Buffer) _}
      if not assigned(FOnBufferInvalid) then raise Exception.create(Cons_Err_Buffer)
      else {_ NOT if not assigned(FOnBufferInvalid) then raise Exception.create(Cons_Err_Buffer) _}
        begin
          Handled := FALSE;
          FOnBufferInvalid(Handled, Buff, length);
          if not Handled then raise Exception.create(Cons_Err_Buffer)
          else {_ NOT if not Handled then raise Exception.create(Cons_Err_Buffer) _}  CTry := CTry + 1;
        end; {_ NOT if not assigned(FOnBufferInvalid) then raise Exception.create(Cons_Err_Buffer) _}
  Canceled := FALSE; {Turn Canceled off}
  ResolveRemoteHost; {Resolve the IP address of remote host}
  if RemoteAddress.sin_addr.S_addr = 0 then
    raise UDPSockError.create(Cons_Err_Addr); {If Resolving failed raise exception}
  StatusMessage(Status_Basic, Cons_Msg_Data); {Inform status}
  RemoteAddress.sin_family := AF_INET; {Make connected true}
{$R-}
  RemoteAddress.sin_port := htons(FRemotePort); {If no proxy get port from Port property}
{$R+}
  i := SizeOf(RemoteAddress); {i := size of remoteaddress structure}
  WinSock.SendTo(ThisSocket, Buff, length, 0, RemoteAddress, i);
  if assigned(FOnDataSend) then FOnDataSend(self);
end; {_ procedure TNMUDPEX.SendBuffer(Buff: array of char; length: integer); _}
{*******************************************************************************************
Handle Power socket error
********************************************************************************************}

function TNMUDPEX.ErrorManager(ignore: word): string;
var
  slasterror: string;
begin
  StatusMessage(STATUS_TRACE, Cons_Msg_Echk); {Report Status}
  FLastErrorno := wsagetlasterror; {Set last error}
  if (FLastErrorno and ignore) <> ignore then
      {If the error is not the error to be ignored}
    begin
      slasterror := SocketErrorStr(FLastErrorno); {Get the description string for error}
      if assigned(fonerrorevent) then
         {If error handler present excecute it}
        FOnerrorEvent(Self, FLastErrorno, slasterror);
      raise UDPSockError.create(slasterror); {Raise exception}
    end; {_ if (FLastErrorno and ignore) <> ignore then _}
  result := slasterror; {return error string}
end; {_ function TNMUDPEX.ErrorManager(ignore: word): string; _}

{*******************************************************************************************
Return Error Message Corresponding To Error number
********************************************************************************************}

function TNMUDPEX.SocketErrorStr(ErrNo: word): string;
begin
  if ErrNo <> 0 then
      {If error exits}
    begin
      (*for x := 0 to 50 do                                {Get error string}
        if winsockmessage[x].errorcode = errno then
          Result := inttostr( winsockmessage[x].errorcode ) + ':' + winsockmessage[x].text; *)
      if Result = '' then {If not found say unknown error}
        Result := Cons_Msg_Eno + IntToStr(ErrNo);
    end; {_ if ErrNo <> 0 then _}
  StatusMessage(Status_DEBUG, Cons_Msg_ELkp + result); {Status message}
end; {_ function TNMUDPEX.SocketErrorStr(ErrNo: word): string; _}

{*******************************************************************************************
Output a Status message: depends on current Reporting Level
********************************************************************************************}

procedure TNMUDPEX.StatusMessage(Level: byte; value: string);
begin
  if level <= FReportLevel then
      {If level of error less than present report level}
    begin
      _status := value; {Set status to vale of error}
      if assigned(FOnStatus) then
        FOnStatus(self, _status); {If Status handler present excecute it}
    end; {_ if level <= FReportLevel then _}
end; {_ procedure TNMUDPEX.StatusMessage(Level: byte; value: string); _}

{*******************************************************************************************
Socket Message handler
********************************************************************************************}

procedure TNMUDPEX.WndProc(var message: TMessage);
begin
  if _ProcMsg then {If Processing of messages enabled}
    with message do
      if msg = WM_ASYNCHRONOUSPROCESS then
        begin
          if lparamLo = FD_Read then
            ProcessIncomingdata
          else {_ NOT if lparamLo = FD_Read then _}
            begin
              wait_flag := TRUE;
              if lparamhi > 0 then
                  {If no error}
                Succeed := FALSE {Succed flag not set}
              else {_ NOT if lparamhi > 0 then _}
                Succeed := TRUE;
            end; {_ NOT if lparamLo = FD_Read then _}
          SetEvent(EventHandle);
        end {_ if msg = WM_ASYNCHRONOUSPROCESS then _}
      else
        Result := DefWindowProc(FSocketWindow, Msg, wParam, lParam);
end; {_ procedure TNMUDPEX.WndProc(var message: TMessage); _}


procedure TNMUDPEX.ProcessIncomingdata;
var
  From: TSockAddr;
  i: integer;
  s1: string;
  p1: u_short;

begin
  i := sizeof(From);
  IBuffSize := Winsock.RecvFrom(ThisSocket, IBuff, DataPackSize, 0, From, i);        /////lsyx
  if assigned(FOnDataReceived) then
    begin
      s1 := format('%d.%d.%d.%d', [ord(From.sin_addr.S_un_b.S_b1), ord(From.sin_addr.S_un_b.S_b2), ord(From.sin_addr.S_un_b.S_b3), ord(From.sin_addr.S_un_b.S_b4)]);
      p1 := ntohs(From.sin_port);
      FOnDataReceived(self, IBuffSize, s1, p1);
    end; {_ if assigned(FOnDataReceived) then _}
end; {_ procedure TNMUDPEX.ProcessIncomingdata; _}

procedure TNMUDPEX.ReadStream(DataStream: TStream);

begin
  DataStream.WriteBuffer(IBuff, IBuffSize);
  DataStream.position := 0;
end; {_ procedure TNMUDPEX.ReadStream(DataStream: TStream); _}

procedure TNMUDPEX.Wait;
begin
  WaitforSync(EventHandle);
  ResetEvent(EventHandle);
end;

procedure TNMUDPEX.ReadBuffer(var Buff: array of char; var length: integer);

begin
  Move(IBuff, Buff, IBuffSize);
  length := IBuffSize;
end; {_ procedure TNMUDPEX.ReadBuffer(var Buff: array of char; var length: integer); _}

end.

⌨️ 快捷键说明

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