Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];

Вниз

idudpserver1   Найти похожие ветки 

 
ZDDR ©   (2004-05-11 00:09) [0]

почему после кода:

idudpserver1.Active:=false;
idudpserver1.DefaultPort:=strtoint("1005"); idudpserver1.Active:=true;
idudpserver1 перестает получать broadcast сообщения???  


 
Rouse_ ©   (2004-05-11 08:53) [1]

А ты проверь сначала, он вообще получает какие нибудь сообщения на 1005 порт? даже не броадкастом...


 
ZDDR ©   (2004-05-11 10:45) [2]

получает


 
ZDDR ©   (2004-05-11 10:48) [3]

все работает нормально сообщения принимаются по 1005 порту но стоит выполнить код:
idudpserver1.active:=false;
idudpserver1.defaultport:=strtoint("1005");
idudpserver1.active:=true;

перестают преходить сообщения


 
Rouse_ ©   (2004-05-11 12:42) [4]

Я имею ввиду после этого кода он получает обычные сообщения на этот порт? Не трогай пока броадкасты...


 
Zulus   (2004-05-11 20:57) [5]

У меня такой же вопрос. Необходимо в процессе работы программы менять UDP Port. Как это сделать??? Подскажите плиз.


 
Rouse_ ©   (2004-05-11 21:43) [6]

Так вот: даже если сделать ему Active False а потом True, даже без измения порта, наступает кирдык...

Вот для этого я и писал собственные реализации UDP, так как в Индийском - попросту немного запутался с ихней реализацией и не смог выяснить причины глюка... :(


 
Zulus   (2004-05-11 22:11) [7]

Уважаемый, Rouse_ ©, а Вы не могли бы поделиться своим опытом и помочь в решении момей проблемы. Очень надо...


 
Rouse_ ©   (2004-05-11 23:08) [8]

Ну вот как пример...
За проверками не следил, могут быть ошибки - но так проверил, вроде работает:

unit FWUDPSocket;

interface

uses
 Windows, Messages, Winsock, SysUtils, Classes, WSAErrors, Forms;

resourcestring
 ERR_ERROR   = "FWSocket error. ";
 ERR_CREATE  = "Can not initialize WSA. ";
 ERR_SOCKET  = "Can not create socket. ";
 ERR_SEND    = "Can not send data. ";
 ERR_BIND    = "Can not bind socket. ";
 ERR_SSO     = "Can not set socket option. ";

const
 HST_BROADCAST: String = "255.255.255.255";
 MAX_UDP_SIZE: Integer = 8192;
 WM_ASYNC = WM_USER + 1;

type

 TFWSocketErrorEvent = procedure(Sender: TObject; Error: String) of object;
 TFWSocketOnReadStringEvent = procedure(Sender: TObject; FromIP, Data: String) of object;
 TFWSocketOnReadStreamEvent = procedure(Sender: TObject; FromIP: String; Data: TMemoryStream) of object;

 TFWUDPSocket = class(TComponent)
 private
   FHandle: HWND;
   FServer, FClient: TSocket;
   FActive: Boolean;
   FWSAData: TWSAData;
   FSockAddr: TSockAddrIn;
   FOnError: TFWSocketErrorEvent;
   FOnReadString: TFWSocketOnReadStringEvent;
   FOnReadStream: TFWSocketOnReadStreamEvent;
   FPort: Integer;
   FWarning: String;
   function GetActive: Boolean;
   procedure SetActive(const Value: Boolean);
   procedure SetPort(const Value: Integer);
 protected
   procedure SockWND(var AMsg: TMessage); message WM_ASYNC;
   procedure Error(const Value: String);
   function Initialize(var FSocket: TSocket; const Host: String; const Port: Integer; Server: Boolean = False): Boolean;
   procedure DeInitialize(Server: Boolean = False);
   function GetIp: String;
 public
   procedure Broadcast(const Port: Integer; Data: String);
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
   procedure AfterConstruction; override;
   procedure Send(const Host: String; Port: Integer; Data: String); overload;
   procedure Send(const Host: String; Port: Integer; Data: TMemoryStream); overload;
 published
   property Port: Integer read FPort write SetPort;
   property Active: Boolean read GetActive write SetActive default False;
   property OnError: TFWSocketErrorEvent read FOnError write FOnError;
   property OnReadString: TFWSocketOnReadStringEvent read FOnReadString write FOnReadString;
   property OnReadStream: TFWSocketOnReadStreamEvent read FOnReadStream write FOnReadStream;
 end;

procedure Register;


 
Rouse_ ©   (2004-05-11 23:09) [9]

implementation

procedure Register;
begin
 RegisterComponents("Fangorn Wizards Lab", [TFWUDPSocket]);
end;

{ TFWUDPSocket }

procedure TFWUDPSocket.AfterConstruction;
begin
 inherited;
 if FWarning <> "" then
   if Assigned(FOnError) then
    FOnError(Self, FWarning);
end;

procedure TFWUDPSocket.Broadcast(const Port: Integer; Data: String);
var
 Result: Integer;
begin

 try

   if not Initialize(FClient, HST_BROADCAST, Port) then Exit;

   Result := SendTo(FClient, Data[1], Length(Data), 0, FSockAddr, SizeOf(FSockAddr));

   if Result = SOCKET_ERROR then
     Error(ERR_SEND + WSAErrorToString(WSAGetLastError));

 finally

   DeInitialize;

   if WSAGetLastError <> 0 then Error(WSAErrorToString(WSAGetLastError));

 end;

end;

constructor TFWUDPSocket.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FActive := False;
 FPort := 6767;
 FClient := 0;
 FServer := 0;
 if not (csDesigning in ComponentState) then
     FHandle := AllocateHWnd(SockWND);
end;

procedure TFWUDPSocket.DeInitialize(Server: Boolean = False);
begin

 if Server then
 begin

   if FServer <> 0 then
   begin

     WSAAsyncSelect(FServer, FHandle, 0, 0);

     closesocket(FServer);
     FServer := 0;

     WSACleanup;

   end;

 end
 else

   if FClient <> 0 then
   begin

     closesocket(FClient);
     FClient := 0;

     WSACleanup;

   end;

end;

destructor TFWUDPSocket.Destroy;
begin
 DeInitialize;
 DeInitialize(True);
 DeallocateHWnd(FHandle);
 inherited;
end;

procedure TFWUDPSocket.Error(const Value: String);
begin
 if Assigned(FOnError) then
  FOnError(Self, ERR_ERROR + Value)
 else
   FWarning := ERR_ERROR + Value;
end;


 
Rouse_ ©   (2004-05-11 23:09) [10]

function TFWUDPSocket.GetActive: Boolean;
begin
 if (csDesigning in ComponentState) then
   Result := FActive
 else
 begin
   Result := False;
   if (FHandle <> 0) and
      (FServer <> 0) and
      FActive
     then
       Result := True;
 end;
end;

function TFWUDPSocket.GetIp: String;
var
 WSAData: TWSAData;
 HostEnt: PHostEnt;
 Name: array [0..$FF] of Char;
begin
 WSAStartup($0101, WSAData);
 GetHostName(Name, $FF);
 HostEnt := GetHostByName(Name);
 if (HostEnt.h_addr_list^ <> nil) then
   Result := inet_ntoa(PInAddr(HostEnt.h_addr_list^)^);
 WSACleanup;
end;

function TFWUDPSocket.Initialize(var FSocket: TSocket; const Host: String;
 const Port: Integer; Server: Boolean = False): Boolean;
var
 Option: BOOL;
 SrvHost: String;
 Err: Integer;
begin

 Result := False;

 try

   Err := WSAStartup($0101, FWSAData);
   if Err <> 0 then
   begin
     Error(ERR_CREATE + WSAErrorToString(WSAGetLastError));
     Exit;
   end;

   FSocket := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

   if FSocket = INVALID_SOCKET then
   begin
     Error(ERR_SOCKET + WSAErrorToString(WSAGetLastError));
     Exit;
   end;

   Option := True;

   with FSockAddr do
   begin

     if Host = HST_BROADCAST then
     begin

       if Server then
       begin
         SrvHost := GetIp;
         sin_addr.S_addr := inet_addr(PChar(SrvHost));
       end
       else
         sin_addr.S_addr := INADDR_BROADCAST;

       Err := SetSockOpt(FSocket, SOL_SOCKET, SO_BROADCAST, PChar(@Option), SizeOf(Option));
       if Err = SOCKET_ERROR then
       begin
         Error(ERR_SSO + WSAErrorToString(WSAGetLastError));
         Exit;
       end;

     end
     else
       sin_addr.S_addr := inet_addr(PChar(Host));

     sin_port := htons(Port);
     sin_family := AF_INET;
   end;

   if Server then
   begin

     Err := bind(FSocket, FSockAddr, SizeOf(FSockAddr));
     if Err = SOCKET_ERROR then
     begin
       Error(ERR_BIND + WSAErrorToString(WSAGetLastError));
       Exit;
     end;

   end;

   WSASetLastError(0);

   Result := True;

 except

   Error(WSAErrorToString(WSAGetLastError));

 end;

end;


 
Rouse_ ©   (2004-05-11 23:09) [11]

procedure TFWUDPSocket.Send(const Host: String; Port: Integer;
 Data: String);
var
 Result: Integer;
begin

 try

   if not Initialize(FClient, Host, Port) then Exit;

   Result := SendTo(FClient, Data[1], Length(Data), 0, FSockAddr, SizeOf(FSockAddr));

   if Result = SOCKET_ERROR then
     Error(ERR_SEND + WSAErrorToString(WSAGetLastError));

 finally

   DeInitialize;

   if WSAGetLastError <> 0 then Error(WSAErrorToString(WSAGetLastError));

 end;

end;

procedure TFWUDPSocket.Send(const Host: String; Port: Integer;
 Data: TMemoryStream);
var
 Buffer: array of Char;
 Result: Integer;
begin

 try

   if not Initialize(FClient, Host, Port) then Exit;

   SetLength(Buffer, Data.Size);
   Data.Position := 0;
   Data.ReadBuffer(Buffer[0], Data.Size);

   Result := SendTo(FClient, Buffer[0], Data.Size, 0, FSockAddr, SizeOf(FSockAddr));

   if Result = SOCKET_ERROR then
     Error(ERR_SEND + WSAErrorToString(WSAGetLastError));

 finally

   SetLength(Buffer, 0);
   DeInitialize;

   if WSAGetLastError <> 0 then Error(WSAErrorToString(WSAGetLastError));

 end;

end;


 
Rouse_ ©   (2004-05-11 23:10) [12]

procedure TFWUDPSocket.SetActive(const Value: Boolean);
var
 Err: Integer;
begin

 if FActive = Value then
   Exit
 else
   FActive := Value;

 if (csDesigning in ComponentState) then Exit;

 if FActive then
 begin

   if FServer <> 0 then DeInitialize(True);

   if Initialize(FServer, HST_BROADCAST, FPort, True) then
   begin
     Err := WSAAsyncSelect(FServer, FHandle, WM_ASYNC, FD_READ);
     if Err = SOCKET_ERROR then
     begin
       Error(WSAErrorToString(WSAGetLastError));
       DeInitialize(True);
       FActive := False;
       Exit;
     end;
   end
   else
   begin
     DeInitialize(True);
     FActive := False;
   end;
     
 end
 else
   DeInitialize(True);

 Sleep(100);

end;

procedure TFWUDPSocket.SetPort(const Value: Integer);
var
 Err: Integer;
begin

 if FPort = Value then
   Exit
 else
   FPort := Value;

 if (csDesigning in ComponentState) then Exit;

 if FServer <> 0 then DeInitialize(True);

 if FActive then
   if Initialize(FServer, HST_BROADCAST, FPort, True) then
   begin
     Err := WSAAsyncSelect(FServer, FHandle, WM_ASYNC, FD_READ);
     if Err = SOCKET_ERROR then
     begin
       Error(WSAErrorToString(WSAGetLastError));
       DeInitialize(True);
       FActive := False;
       Exit;
     end;
   end
   else
   begin
     DeInitialize(True);
     FActive := False;
   end;

 Sleep(100);

end;
     
procedure TFWUDPSocket.SockWND(var AMsg: TMessage);
var
 Err: Integer;
 SockAddr: TSockAddrIn;
 Size, RcvCount: Integer;
 Buffer: array [0..8191] of Char;
 ResultString, FromIP: String;
 MemoryStream: TMemoryStream;
begin

 with AMsg do
   case Msg of
   WM_ASYNC:
   begin

     Err := WSAGetSelectError(LParam);
     if Err <> 0 then
     begin
       Error(WSAErrorToString(Err));
       Exit;
     end;

     case WSAGetSelectEvent(LParam) of
       FD_READ:
       begin

         FillChar(Buffer, 8192, #0);

         Size := SizeOf(SockAddr);
         RcvCount := recvfrom(WParam, Buffer[0], MAX_UDP_SIZE, 0, SockAddr, Size);

         if RcvCount <> SOCKET_ERROR then
         begin

           FromIP := inet_ntoa(SockAddr.sin_addr);

           ResultString := StrPas(@Buffer);
           if Assigned(FOnReadString) then
             FOnReadString(Self, FromIP, ResultString);

           MemoryStream := TMemoryStream.Create;
           MemoryStream.Write(Buffer[0], SizeOf(Buffer));
           MemoryStream.Position := 0;
           if Assigned(FOnReadStream) then
             FOnReadStream(Self, FromIP, MemoryStream);
           MemoryStream.Free;

         end
         else
           Error(WSAErrorToString(WSAGetLastError));
         end;
         
       end;
     end;

   else
     DefWindowProc(FHandle, Msg, WParam, LParam);
   end;

end;

end.


Учитывай что это демка а никак не правило написания кода...


 
Rouse_ ©   (2004-05-11 23:38) [13]

Тут нужны небольшие пояснения...
Вся эта чтука работает одновременно и как клиент и как сервер...
т.е. Делаешь ей Active:= True; и сервер запущен, а после этого можешь из нее же делать Broadcast или Send...
времени не много свободного, поэтому слепил все в кучу :)


 
Zulus   (2004-05-11 23:58) [14]

Спасибо огромное и за это. Теперь буду разбираться. Может что и получится. Еще раз спасибо (просто долго искал совета).


 
Verg ©   (2004-05-12 01:23) [15]


> [6] Rouse_ ©   (11.05.04 21:43)


Странно это. По крайней мере на 9.014 версии Indy все работает без вопросов. Хоть с бродкастами, хоть без.


> [3] ZDDR ©   (11.05.04 10:48)
> все работает нормально сообщения принимаются по 1005 порту
> но стоит выполнить код:
> idudpserver1.active:=false;
> idudpserver1.defaultport:=strtoint("1005");
> idudpserver1.active:=true;
>
> перестают преходить сообщения


Как ведется прием датаграмм (где и как выполняется idudpserver1.Receive***)?
При каких обстоятельствах выполняется приведенный код "рестарта" сервера? Т.е. в результате каких событий он вызывается?


 
Rouse_ ©   (2004-05-12 14:47) [16]

> Verg ©   (12.05.04 01:23) [15]
Вполне вероятно - просто у меня шестерка была в то время, а реализовать нужно было все в сжатые сроки - поэтому пришлось ручками, это гораздо проще чем разбираться в чужом коде...



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.029 c
6-1084109098
WHS
2004-05-09 17:24
2004.07.04
winsock


14-1087117490
Piter
2004-06-13 13:04
2004.07.04
Давайте поиграем в ассоциации


3-1086434077
DereK)
2004-06-05 15:14
2004.07.04
Отчет по одной записи


8-1082305824
ARY
2004-04-18 20:30
2004.07.04
Анимация велосипеда.


1-1087724807
Navi
2004-06-20 13:46
2004.07.04
Сетка и рисование в мм





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский