-
Когда создаю TSocketServer на форме, кидая компонент, создаю событие OnRead, всё проходит легко и просто. Но когда создаю в RTTI, то никакие события не вызываются? что я делаю не так? простой пример: unit SS;
interface
uses
Classes, ScktComp, SysUtils;
type TServerThread = class (TThread)
private
SSocket :TServerSocket;
procedure OnRead (Sender: TObject; Socket: TCustomWinSocket);
protected
procedure Execute; override;
public
Constructor Create;
end;
implementation
constructor TServerThread.Create;
begin
inherited Create (false);
SSocket:=TServerSocket.Create(nil);
SSocket.Port:=80;
SSocket.OnClientRead := OnRead;
SSocket.Active:=true;
end;
procedure TServerThread.Execute;
begin
inherited;
self.Priority:=tpLower;
while not self.Terminated do sleep(1);
end;
procedure TServerThread.OnRead(Sender: TObject; Socket: TCustomWinSocket);
var
s: string;
begin
s:= socket.ReceiveText;
Writeln(s);
end;
-
> когда создаю в RTTI
Чавой-то ?
Ты вообще в курсе, что это такое - RTTI ?
> никакие события не вызываются
И не будут "вызываться", поскольку объект класса TServerSocket создается тобой в вызывающем потоке.
> что я делаю не так?
Абсолютно все.
-
наверное приплёл rtti изза real-time... как же создать сервер в отдельном потоке правильно?
-
> как же создать сервер в отдельном потоке правильно? >
Создавать его можно где угодно.
Но активировать его следует в контексте именно того потока. который будет ответственен за диспетчеризацию/выборку/обработку оконных сообщений, возбуждаемых твоими серверными гнездами.
"На огурцах" - активируй/деактивируй свой сервер непосредственно в теле TServerThread.Execute
-
приложение консольное... не думал что это будет иметь значение своего Instance не имеет, windows message не принимает... спасибо буду выкручиваться
-
> не думал что это будет иметь значение
Как оказалось - имеет)
> своего Instance не имеет
Любое приложение имеет свой Instance.
А что он тебя так волнует ? К твоей проблеме это не имеет никакого отношения ...
> windows message не принимает
Ты их у системы не спрашиваешь, вот "оно" их и не принимает.
-
"Ты их у системы не спрашиваешь, вот "оно" их и не принимает." а оно мне их и не даёт GetMessage (msg, 0,0,0); и GetMessage (msg, Handle,0,0); ничего не получают насколько я знаю, чтобы создать hWnd нужен instance instance приложение получает в WinMain в качестве параметра в консольном его нет
-
-
да, есть HInstance получаю с помощью него сообщения но что с ними делать?
-
> GetMessage (msg, 0,0,0); и GetMessage (msg, Handle,0,0); > > ничего не получают
В приведененом тобой коде нет никаких GetMessage.
> чтобы создать hWnd нужен instance
Это не твоя забота.
Невидимое окно, которому слушающее гнездо адресует сообщения о своих событиях, создается неявно при вызове ServerSocket.Open
> instance приложение получает в WinMain в качестве параметра
Ничего подобного)
> в консольном его нет
Кого ?!
-
> instance приложение получает в WinMain в качестве параметра
Пардон, WinMain-то его, конечно, получает, но это не имеет никакого отношения к твоей "проблеме".
-
Невидимое окно, которому слушающее гнездо адресует сообщения о своих событиях, создается неявно при вызове ServerSocket.Open если оно создаётся, то почему я нечего не получаю? сделать в Execute ни к чему не приводит
constructor TServerThread.Create;
begin
inherited Create (false);
SSocket:=TServerSocket.Create(nil);
end;
procedure TServerThread.Execute;
begin
inherited;
SSocket.Port:=80;
SSocket.OnClientRead := OnRead;
SSocket.Active:=true;
while not self.Terminated do sleep(1);
end;
-
вставив в Exetune while GetMessage(msg, 0,0,0)
do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end; всё наконецто заработало...
-
> TranslateMessage(Msg);
Это лишнее.
> всё наконецто заработало
А где реакция на команду терминирования потока ?
-
> procedure TServerThread.Execute; > begin > inherited;
Это зачем ?
-
> > procedure TServerThread.Execute; > > begin > > inherited; > > > Это зачем ?
остался от ctrl+shift+c для абстрактного метода бессмысленно вызывать по поводу terminate в OnTerminate server.close; это просто быстросделанный unit , чтобы показать что я делаю с TServerSocket
-
> по поводу terminate > в OnTerminate server.close;
OnTerminate - это уже следствие, а не причина.
А причина - это корректное завершение выполнения метода Execute.
А Execute у тебя не завершится по кр.мере до момента обнаружения взведенного флага Terminated.
А флаг Terminated ты не можешь проанализировать, пока ты "висишь" на блокирующем вызове GetMessage
Фершейн, надеюсь ?)
-
procedure TServer.Close;
begin
PostThreadMessage(ThreadID,WM_QUIT,0,0);
end;
PostQuitMessage(0); не работает, хотя должен вызывать WM_QUIT в примере FearG0 © [7] вызывается WM_CLOSE, но, насколько я знаю, WM_QUIT - единственный кто вызывает у метода GetMessage = false
-
неблокирующий сокет - зло program CharGen;
uses SysUtils,ScktComp,WinSock;
type
TServerClientThreadEx=class(TServerClientThread)
protected
procedure ClientExecute; override;
end;
procedure TServerClientThreadEx.ClientExecute;
var i:integer;
begin
Randomize;
while (not Terminated) and ClientSocket.Connected do
begin
try
i:=Random(MaxInt);
ClientSocket.SendBuf(i,SizeOf(i));
except
Terminate;
HandleException;
end;
end;
end;
procedure GetThread(Self:TObject;Sender: TObject;ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread);
begin
writeln('GetThreadEvent ',ClientSocket.RemoteAddress,':',ClientSocket.RemotePort);
SocketThread:=TServerClientThreadEx.Create(false,ClientSocket);
end;
function Proc2Method(Code, Data: Pointer):TMethod;
begin
result.Code:=Code;
result.Data:=Data;
end;
var Server:TServerSocket;
begin
Server:=TServerSocket.Create(nil);
try
Server.ServerType:=stThreadBlocking;
Server.Port:=3128;
Server.OnGetThread:=TGetThreadEvent(Proc2Method(@GetThread,Server));
Server.Open;
while Server.Active do Sleep(100);
finally
Server.Free;
end;
end.
-
> Slym © (03.10.07 05:54) [18] > > неблокирующий сокет - зло
Притчу про "всякий овощ .." помнишь ?)
|