Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.08.31;
Скачать: CL | DM;

Вниз

TSocketServer без формы   Найти похожие ветки 

 
Obsidee   (2007-10-02 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;


 
Сергей М. ©   (2007-10-02 13:49) [1]


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


Чавой-то ?

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


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


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


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


Абсолютно все.


 
Obsidee   (2007-10-02 14:04) [2]

наверное приплёл rtti изза real-time...
как же создать сервер в отдельном потоке правильно?


 
Сергей М. ©   (2007-10-02 14:12) [3]


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


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

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

"На огурцах" - активируй/деактивируй свой сервер непосредственно в теле TServerThread.Execute


 
Obsidee   (2007-10-02 15:15) [4]

приложение консольное... не думал что это будет иметь значение
своего Instance не имеет, windows message не принимает...
спасибо
буду выкручиваться


 
Сергей М. ©   (2007-10-02 15:23) [5]


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


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


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


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

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


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


Ты их у системы не спрашиваешь, вот "оно" их и не принимает.


 
Obsidee   (2007-10-02 15:51) [6]

"Ты их у системы не спрашиваешь, вот "оно" их и не принимает."
а оно мне их и не даёт
GetMessage (msg, 0,0,0); и GetMessage (msg, Handle,0,0);
ничего не получают
насколько я знаю, чтобы создать hWnd нужен instance
instance приложение получает в WinMain в качестве параметра
в консольном его нет


 
FearG0 ©   (2007-10-02 15:54) [7]

http://delphimaster.net/view/6-1191102532/

Загляни в эту ветку, там обсуждаем реализацию TClientSocket, но по сути все точь в точь и синтаксис один и тот же практически.


 
Obsidee   (2007-10-02 15:56) [8]

да, есть HInstance
получаю с помощью него сообщения
но что с ними делать?


 
Сергей М. ©   (2007-10-02 16:00) [9]


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


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


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


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

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


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


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


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


Кого ?!


 
Сергей М. ©   (2007-10-02 16:06) [10]


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


Пардон, WinMain-то его, конечно, получает, но это не имеет никакого отношения к твоей "проблеме".


 
Obsidee   (2007-10-02 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   (2007-10-02 16:29) [12]

вставив в Exetune
while GetMessage(msg,  0,0,0)
do begin
   TranslateMessage(Msg);
   DispatchMessage(Msg);  
end;

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


 
Сергей М. ©   (2007-10-02 16:33) [13]


> TranslateMessage(Msg);


Это лишнее.


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


А где реакция на команду терминирования потока ?


 
Сергей М. ©   (2007-10-02 16:34) [14]


> procedure TServerThread.Execute;
> begin
> inherited;


Это зачем ?


 
Obsidee   (2007-10-02 17:02) [15]


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

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

по поводу terminate
в OnTerminate server.close;
это просто быстросделанный unit, чтобы показать что я делаю с TServerSocket


 
Сергей М. ©   (2007-10-02 17:11) [16]


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


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

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

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

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

Фершейн, надеюсь ?)


 
Obsidee   (2007-10-02 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 ©   (2007-10-03 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.


 
Сергей М. ©   (2007-10-03 08:20) [19]


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


Притчу про "всякий овощ .." помнишь ?)


 
DiamondShark ©   (2007-10-03 15:20) [20]


> неблокирующий сокет - зло

Зло, бес с порно.
Сокетные компоненты (по кр.м., в исполнении борманда) -- ещё большее зло.


> Притчу про "всякий овощ .." помнишь ?)

Это не овощ, это сорняк-мутант.


 
DVM ©   (2007-10-03 15:38) [21]


> > неблокирующий сокет - зло
>
> Зло, бес с порно.

Почему зло?


 
DVM ©   (2007-10-03 15:39) [22]

И не надо путать неблокирущие и асинхронные сокеты. Это не одно и то же.


 
Сергей М. ©   (2007-10-03 15:49) [23]


> Сокетные компоненты (по кр.м., в исполнении борманда) --
>  ещё большее зло


"Вы не любите кошек ? Да вы просто не умеете их готовить !" (С)


> это сорняк-мутант


Ну да.

А аргументы, конечно же, - "наследие царского режима")


 
DiamondShark ©   (2007-10-03 17:25) [24]


> DVM ©   (03.10.07 15:38) [21]
> Почему зло?

Потому что, как тут верно, но не полно вспомнили, "наследие царского режима".


> DVM ©   (03.10.07 15:39) [22]
> И не надо путать неблокирущие и асинхронные сокеты. Это
> не одно и то же.

Не напомнишь, кто, где и когда утверждал, что это одно и то же?


> Сергей М. ©   (03.10.07 15:49) [23]
> "Вы не любите кошек ? Да вы просто не умеете их готовить
> !" (С)

Я так понял, это был Аргумент?


> А аргументы, конечно же, - "наследие царского режима")

Не затруднит напомнить полную версию текста, откуда ты отквоченное выдрал?
Как только сподобишься, получишь аргумент на "сорняк".
А "мутант" -- так это борландовское исполнение обёртки, к которой две основные претензии:

1. Мутное обращение с сущностями.
Не вводится никакой новой абстракции. Нафига объектная обёртка? Ладно, допустим, для батонокидательства. Но экономия трудоёмкости мизерная, объём рукописного кода соизмерим с прямым использованием WS API.
Смешиваются сущности. В блокирующем и неблокирующем режимах используются разные наборы методов (либо общие методы, но изобилующие if Block then ... else ...), это наводит на мысль о разных ветвях наследования.

2. Сокрытая сложность и неочевидные требования к окружению.
В неблокирующем режиме компоненты используют механизм оконных сообщений и, как следствие, требуют message pump. Эта зависимость от окружения не только не очевидна из публичного интерфейса классов, но даже не отражена в документации. Обнаружить эту особенность можно либо стукнувшись лбом (как в субже), либо зная детали реализации (тогда вопрос: нафиг нужны такие weak-incapsulated компоненты?).


 
DVM ©   (2007-10-03 17:34) [25]


> Потому что, как тут верно, но не полно вспомнили, "наследие
> царского режима".

Наследие это асинхронные сокеты на сообщениях, а не неблокирующие. А говорите, что не путаете. Неблокирующие сокеты ничем не хуже и не лучше блокирующих, были и есть и используются и в Unix и в Windows. А вот асинхронные сокеты на сообщениях - это изобретение MS для ранних версий Win (3.11), так как в них с многопоточностью было все не очень гладко.


 
DVM ©   (2007-10-03 17:40) [26]

Просто так сложилось, что в Windows асинхронные сокеты - это всегда неблокирующие сокеты, но неблокирующие сокеты - это не всегда асинхронные.


 
DiamondShark ©   (2007-10-03 18:56) [27]


> DVM ©   (03.10.07 17:34) [25] [26]

Это всё понятно.
Только вот в компонентах под "неблокирующими" подразумеваются именно асинхронные сокеты на сообщениях.


> Просто так сложилось, что в Windows асинхронные сокеты -
>  это всегда неблокирующие сокеты

Ну, теперь уже не всегда. Есть ведь overlapped IO, что намного удобнее.


 
Slym ©   (2007-10-04 04:51) [28]

DiamondShark ©   (03.10.07 17:25) [24]
Я для себя сделал BlockScktComp - взял стандартный ScktComp и вырезал от туда всю асинхронику


 
Evgeny V ©   (2007-10-04 07:06) [29]


> DiamondShark ©   (03.10.07 18:56) [27]


> Ну, теперь уже не всегда. Есть ведь overlapped IO, что намного
> удобнее.


В Windows всегда.
MSDN ioctlsocket


> The WSAAsyncSelect and WSAEventSelect functions automatically
> set a socket to nonblocking mode


Оно и понятно, что сокет должен быть неблокирующим. Иначе как бы мы могли вызвав recv, потом в этом же потоке подождать события функцией   WSAWaitForMultipleEvents, ибо висели бы на вызове recv, если сокет блокирующий.


 
Evgeny V ©   (2007-10-04 10:24) [30]


> DiamondShark ©   (03.10.07 18:56) [27]


Хотя извиняюсь, в

> Evgeny V ©   (04.10.07 07:06) [29]

я наврал. С оверлаппед сокетами все сложнее. Просто подзабыл что EventSelect и overlapped сокеты это разное:-)


 
VaRela   (2007-10-19 12:45) [31]

Доброе время суток всем, борюсь со следующей проблемой:
TServerSocket работает в блокирующем режиме, создал своего наследника для потока TServerClientThread. В ClientExecute вертится следующий цикл (прошу прощения что BCB):

while (!Terminated && ClientSocket->Connected)
{
.....
}

Цикл работает отлично, но при отключении клиента НЕ ЗАВЕРШАЕТСЯ!, никак не соображу почему.
Как можно узнать что клиент отключился?

P.S. Клиент не мой, переписать не смогу, протокола не знаю. :-)



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

Текущий архив: 2008.08.31;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.015 c
11-1193002581
Elec3C
2007-10-22 01:36
2008.08.31
Системное меню Edit а


2-1216785438
Zergost
2008-07-23 07:57
2008.08.31
Фильтрация по полям?


3-1204739910
Tomkat
2008-03-05 20:58
2008.08.31
ошибка UDF


15-1215799808
Поросенок Винни-Пух
2008-07-11 22:10
2008.08.31
Непонятно с Дефо


15-1215717772
Пробегал2....
2008-07-10 23:22
2008.08.31
Куда двигаться после delphi?