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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.008 c
10-1150122111
wp2
2006-06-12 18:21
2008.08.31
Как узнать сколько страниц в документе Ворд


3-1204794614
patrick1968
2008-03-06 12:10
2008.08.31
из ADO в PARADOX


11-1192910752
Виктор007
2007-10-21 00:05
2008.08.31
Ошибка в TBitBtn при включенном GRAPHCTL_XPSTYLES


2-1216973773
Vlad Oshin
2008-07-25 12:16
2008.08.31
почему выдает AV ?


4-1194955541
Tahion2
2007-11-13 15:05
2008.08.31
Смена иконки папки в Висте





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский