Конференция "Сети" » TSocketServer без формы [D7, Win2k]
 
  • Obsidee (02.10.07 13:35) [0]
    Когда создаю 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;

  • Сергей М. © (02.10.07 13:49) [1]

    > когда создаю в RTTI


    Чавой-то ?

    Ты вообще в курсе, что это такое - RTTI ?


    > никакие события не вызываются


    И не будут "вызываться", поскольку объект класса TServerSocket создается тобой в вызывающем потоке.


    > что я делаю не так?


    Абсолютно все.
  • Obsidee (02.10.07 14:04) [2]
    наверное приплёл rtti изза real-time...
    как же создать сервер в отдельном потоке правильно?
  • Сергей М. © (02.10.07 14:12) [3]

    > как же создать сервер в отдельном потоке правильно?
    >


    Создавать его можно где угодно.

    Но активировать его следует в контексте именно того потока. который будет ответственен за диспетчеризацию/выборку/обработку оконных сообщений, возбуждаемых твоими серверными гнездами.

    "На огурцах" - активируй/деактивируй свой сервер непосредственно в теле TServerThread.Execute
  • Obsidee (02.10.07 15:15) [4]
    приложение консольное... не думал что это будет иметь значение
    своего Instance не имеет, windows message не принимает...
    спасибо
    буду выкручиваться
  • Сергей М. © (02.10.07 15:23) [5]

    > не думал что это будет иметь значение


    Как оказалось - имеет)


    > своего Instance не имеет


    Любое приложение имеет свой Instance.

    А что он тебя так волнует ? К твоей проблеме это не имеет никакого отношения ...


    > windows message не принимает


    Ты их у системы не спрашиваешь, вот "оно" их и не принимает.
  • Obsidee (02.10.07 15:51) [6]
    "Ты их у системы не спрашиваешь, вот "оно" их и не принимает."
    а оно мне их и не даёт
    GetMessage (msg, 0,0,0);

    и
    GetMessage (msg, Handle,0,0);


    ничего не получают
    насколько я знаю, чтобы создать hWnd нужен instance
    instance приложение получает в WinMain в качестве параметра
    в консольном его нет
  • FearG0 © (02.10.07 15:54) [7]
    http://pda.delphimaster.net/?id=1191102532&n=4

    Загляни в эту ветку, там обсуждаем реализацию TClientSocket, но по сути все точь в точь и синтаксис один и тот же практически.
  • Obsidee (02.10.07 15:56) [8]
    да, есть HInstance
    получаю с помощью него сообщения
    но что с ними делать?
  • Сергей М. © (02.10.07 16:00) [9]

    > GetMessage (msg, 0,0,0); и GetMessage (msg, Handle,0,0);
    >
    > ничего не получают


    В приведененом тобой коде нет никаких GetMessage.


    > чтобы создать hWnd нужен instance


    Это не твоя забота.

    Невидимое окно, которому слушающее гнездо адресует сообщения о своих событиях, создается неявно при вызове ServerSocket.Open


    > instance приложение получает в WinMain в качестве параметра


    Ничего подобного)


    > в консольном его нет


    Кого ?!
  • Сергей М. © (02.10.07 16:06) [10]

    > instance приложение получает в WinMain в качестве параметра


    Пардон, WinMain-то его, конечно, получает, но это не имеет никакого отношения к твоей "проблеме".
  • Obsidee (02.10.07 16:22) [11]
    Невидимое окно, которому слушающее гнездо адресует сообщения о своих событиях, создается неявно при вызове 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;

  • Obsidee (02.10.07 16:29) [12]
    вставив в Exetune
    while GetMessage(msg,  0,0,0)
    do begin
       TranslateMessage(Msg);
       DispatchMessage(Msg);  
    end;


    всё наконецто заработало...
  • Сергей М. © (02.10.07 16:33) [13]

    > TranslateMessage(Msg);


    Это лишнее.


    > всё наконецто заработало


    А где реакция на команду терминирования потока ?
  • Сергей М. © (02.10.07 16:34) [14]

    > procedure TServerThread.Execute;
    > begin
    > inherited;


    Это зачем ?
  • Obsidee (02.10.07 17:02) [15]

    > > procedure TServerThread.Execute;
    > > begin
    > > inherited;
    >
    >
    > Это зачем ?

    остался от ctrl+shift+c
    для абстрактного метода бессмысленно вызывать

    по поводу
    terminate


    в OnTerminate
    server.close;


    это просто быстросделанный
    unit

    , чтобы показать что я делаю с
    TServerSocket

  • Сергей М. © (02.10.07 17:11) [16]

    > по поводу terminate
    > в OnTerminate server.close;


    OnTerminate - это уже следствие, а не причина.

    А причина - это корректное завершение выполнения метода Execute.

    А Execute у тебя не завершится по кр.мере до момента обнаружения взведенного флага Terminated.

    А флаг Terminated ты не можешь проанализировать, пока ты "висишь" на блокирующем вызове GetMessage

    Фершейн, надеюсь ?)
  • Obsidee (02.10.07 17:55) [17]
    procedure TServer.Close;
    begin
     PostThreadMessage(ThreadID,WM_QUIT,0,0);
    end;




    PostQuitMessage(0);

    не работает, хотя должен вызывать WM_QUIT
    в примере FearG0 © [7] вызывается WM_CLOSE, но, насколько я знаю, WM_QUIT - единственный кто вызывает у метода
    GetMessage =

    false
  • Slym © (03.10.07 05:54) [18]
    неблокирующий сокет - зло

    program CharGen;
    {$APPTYPE CONSOLE}

    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.

  • Сергей М. © (03.10.07 08:20) [19]

    > Slym ©   (03.10.07 05:54) [18]
    >
    > неблокирующий сокет - зло


    Притчу про "всякий овощ .." помнишь ?)
 
Конференция "Сети" » TSocketServer без формы [D7, Win2k]
Есть новые Нет новых   [134431   +10][b:0][p:0.003]