Конференция "Сети" » TTCPServer [D7, WinXP]
 
  • Саша (20.04.11 16:19) [0]
    Доброе время суток.
    перекопал весь инет :-)
    я так понимаю нормальное мультипоточное серверное приложение на TTCPServer создать нельзя?
    интерес чисто спортивный.
    вопросов много - ответы в основной юзай то и другое, Indy, или TServerSocket ... а хотелось бы докопаться до истины ...

    procedure TForm1.TcpServer1GetThread(Sender: TObject;
     var ClientSocketThread: TClientSocketThread);
    begin
    ClientSocketThread:=MyThread.Create (TCPServer1.ServerSocketThread);
    end;

    после коннекта MyThread.Execute работает, но MyThread.ClientSocket ПУСТОЙ...

    что я не так понимаю про этот компонент (насколько я понял в TServerSocket все выглядит примерно так же, но ClientSocket передается параметром в GetThread)

    в инете не нашел рабочего примера!

    если кто что объяснит заранее спасибо
  • Eraser © (20.04.11 18:54) [1]
    >
    >
    > [0] Саша   (20.04.11 16:19)

    если нужен многопоточный блокирующий TCP сервер - Indy самое оно.
  • Саша (20.04.11 19:05) [2]
    Спасибо  ... Я это уже понял, так скорее всего и сделаю,
    но  - понять до конца хочется ...  :-)
    на этом компоненте вообще никак или просто я чего то не понял :-)
    просто интересно стало, вопросы такие в инете встречаются, а ответов однозначных нет ...
  • Eraser © (20.04.11 19:12) [3]
    > [2] Саша   (20.04.11 19:05)

    начни изучение не с компонентов делфи, а с теории. Какие бывают разновидности сокетов, как с ними работать и т.д.
    А на данном этапе объяснять в чем разница особо не имеет смысла.
  • Сергей М. © (20.04.11 22:18) [4]

    > нормальное мультипоточное серверное приложение на TTCPServer
    > создать нельзя?


    При наличии нормального мозга можно.

    MyThread - это что такое ?
  • Саша (20.04.11 23:09) [5]
    В общем так, вычитал в инете что у TTCPServer'а на событии OnGetThread необходимо создать поток, потомок TClientSocketThread. вот создаю MyThread=class (TClientSocketThread), переписываю у него метод Execute под свои нужды, то есть под обработку конкретного соединения.
    Вот каким образом обратиться к сокету ?
    у TClientSocketThread а соответственно и у MyThread есть свойство ClientSocket

    Насколько я понимаю именно так реализуется работа с TSocketServer

    все работает, Execute выполняется, а ClientSocket нулевой, обращение к нему любое - ошибка программы и все ..

    и вообче :-) напишите если можно плиз работающий пример, просто я искал уже везде, и на англоязычных форумах, люди задают тот же вопрос

    тот же вопрос и на С++ с тем же компонентом, и опять без ответа, вот здесь:
    http://forum.sources.ru/index.php?showtopic=168182

    А вот это убивает надежду разобраться
    http://www.delphimaster.net/view/6-43724

    все таки компонент кривой или руки большого количества людей вместе со мной? :-)
  • Саша (20.04.11 23:12) [6]
    Сорри, опечатка, 'TSocketServer' читать 'TServerSocket'
  • Сергей М. © (21.04.11 16:54) [7]
    Русский понимаешь ?
    MyThread - это что такое ? Какого типа этот идентификатор ?
  • Саша (21.04.11 20:00) [8]
    Сейчас delphi под рукой нет попробую на память, MyThread это тип, потомок от TClientSocketThread. Я все это не сам конечно придумал, не большой спец в дельфи, вычитал в инете ...

    вот часть кода

    MyThread=class (TClientSocketThread)
    ...
    public
    Procedure Execute; Override;
    ....

    procedure TForm1.TcpServer1GetThread(Sender: TObject;
    var ClientSocketThread: TClientSocketThread);
    begin
    ClientSocketThread:=MyThread.Create (TCPServer1.ServerSocketThread);
    end;

    procedure MyThread.Execute;
    begin
    ....
    end;

    если я совсем не ясно выражаюсь, вот в этом примере тот же вопрос и такой же код,
    http://www.delphimaster.net/view/6-43724

    только там TMyClientSocketThread,  а я его просто назвал короче, MyThread
  • Саша (21.04.11 20:09) [9]
    Сорри, не дописал ...
    так вот, все это работает,но почему MyThread.ClientSocket=nil

    запускаеться этот поток, MyThread.Execute, все работает, но MyThread.ClientSocket=nil

    если использовать компонент TServerSocket то все точно так же, но
    procedure TForm1.ServerSocket1GetThread(Sender: TObject; ClientSocket:не_помню_тип ;
    var ClientSocketThread: TClientSocketThread);

    то есть ClientSocket есть

    самый лучший выход - использовать TServerSocket, но хотелось бы понять что не так с TTCPServer
  • Сергей М. © (21.04.11 21:48) [10]
    > MyThread=class (TClientSocketThread)

    Почему не TMyThread >
    По кр.мере вопрос про "это что такое" не возник бы)

    > хотелось бы понять что не так с TTCPServer

    Всё там "так".

    Открой глаза на OnAccept.
  • Саша (21.04.11 22:58) [11]
    Открыл уже, искал уже, читал уже :-)
    в OnAccept можно обработать запрос-ответ, но по-моему только один, а как создать поток для конкретного соединения? или прямо из онаксепта и создавать?
    тогда что такое OnGetthread  и для чего он?
    и все таки, если не сложно, и если это реально, можно готовый работающий примерчик? хотя бы примерчик онаксепта с созданием потока

    насчет ТMyThread тут вы правы, непрофессионализм, я самоучка :-)
  • Slym © (22.04.11 07:27) [12]
    на TServerSocket делай, там все понятно
  • Саша (22.04.11 13:51) [13]
    Вот так я себе это все представляю

    type
    TMyThread=class(TClientSocketThread)
    private
    public
    Procedure Execute;Override;
    end;

    type
     TForm1 = class(TForm)
       TcpServer1: TTcpServer;
       Memo1: TMemo;
       procedure TcpServer1GetThread(Sender: TObject;
       var ClientSocketThread: TClientSocketThread);
     private
       { Private declarations }
     public

       { Public declarations }
     end;

    var
     Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.TcpServer1GetThread(Sender: TObject;
     var ClientSocketThread: TClientSocketThread);
    begin
    ClientSocketThread:=TMyThread.Create(TCPServer1.ServerSocketThread);
    end;

    Procedure TMyThread.Execute;
    Var IP: String;
    Begin
    IP := ClientSocket.RemoteHost;
    Form1.Memo1.Lines.Add(IP);
    end;
    end.

    это вылетает с ошибкой, так как ClientSocket=nil
    если заменить на:

    Procedure TMyThread.Execute;
    Var IP: String;
    Begin
    {IP := ClientSocket.RemoteHost;}
    Form1.Memo1.Lines.Add('qqqqqqqqqqq');
    end;

    то видно что все работает, только с сокетом работать никак...
  • Саша (22.04.11 14:03) [14]
    Прикольно, в хелпе написано

    Creates an instance of a TClientSocketThread object.

    Delphi syntax:

    constructor Create (ServerSocketThread: TServerSocketThread; ClientSocket: TCustomIpClient);

    но второй параметр принимать не хочет, ошибка :-)

    [Error] Unit1.pas(46): ')' expected but ';' found
  • Сергей М. © (22.04.11 14:56) [15]
    В хелпе лажа.

    А суть проста - всякий раз когда сервер готов принимать вх.запросы на соединение от потенциальных клиентов, он возбуждает событие OnGetThread.
    В его Execute обработчике следует вызвать блокирующий Accept и ждать акцепта вновь установленного соединения. Результат акцепта и есть клиентский сокет, с ним можно продолжать работу в этом треде. Успешное акцептирование данного соединения или завершение клиентского треда есть сигнал для возбуждения сервером нового OnGetThread, если не превышено макс.кол-во клиентских тредов - и все по-новой понеслось)
    Эта сказка про белого бычка продолжается вплоть до деактивации сервера.
  • Сергей М. © (22.04.11 14:59) [16]
    Т.е. сервер c пом. события OnGetThread всегда держит на готове "свободный" тред, ожидающий очередное подключение очередного клиента к серверу.
    Как только подключение случилось, тред может продолжать с ним работать, а сервер возбудит (условно) новое OnGetThread.
  • Саша (22.04.11 15:39) [17]
    Спасибо за ответы!

    > В его Execute обработчике следует вызвать блокирующий Accept
    > и ждать акцепта вновь установленного соединения. Результат
    > акцепта и есть клиентский сокет, с ним можно продолжать
    > работу в этом треде

    как это сделать ?
  • Empleado © (22.04.11 17:05) [18]
    1) "MASTERING DELPHI 6" of Marco Cantù
    Chapter 21 • Internet Programming: Sockets and Indy Components

    2)http://podgoretsky.com/ftp/Docs/Delphi/D5/dg/wsocket.html

    3)......
  • Сергей М. © (22.04.11 17:23) [19]
    Нагло тебе соврал)

    Все до смешного проще - твой обработчик OnGetThread даже не обязан создавать экземпляр треда. Т.е. можно даже не обрабатывать OnGetThread - сервер по умолчанию сам создаст экз-р треда.

    Все что нужно - обрабатывать событие OnAccept, в него параметром передается ссылка на экземпляр свежесозданного сокета, ассоциированного с только что акцептированным соединением.
    Весь сеанс работы с клиентом должен вестись в контексте обработчика OnAccept, выход из которого трактуется сервером как завершение сеанса с последующим разрывом соединения.
 
Конференция "Сети" » TTCPServer [D7, WinXP]
Есть новые Нет новых   [134437   +27][b:0][p:0.001]