Форум: "Сети";
Текущий архив: 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