Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Сокеты


Автор: NoliX 28.3.2006, 14:59
Мне нужно, чтобы был один сервер и несколько клиентов, все они стучались бы в один сокет, при этом каждый обрабатывался в отдельном потоке, информацию по этому поводу я нашел в FAQе, но там написано про Сервер, как настроить клиент (TClientSocket)?
Для начала я пытаюсь отправить сообщение от клиента с помощью sendText, если сервер в режиме nonBlocking то все работает, а в режиме с потоками ничего не работает, вот код потока (взят из фака)

Код

unit Unit2;

interface    
uses    
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls;
type    
  EServerThread = class( Exception );    
  // serverthread это потомок TServerClientThread    
  TServerThread = class( TServerClientThread )    
    private    
      fSocketStream : TWinSocketStream;
    public    
      procedure ClientExecute; override;    
      // ClientExecute отменяет    
      // TServerClientThread.ClientExecute
      // и содержит код, который    
      // выполняется при старте потока
  end;    
implementation

uses unit1;

procedure TServerThread.ClientExecute;
begin    
  inherited FreeOnTerminate := TRUE;    
  try    
    fSocketStream := TWinSocketStream.Create( ClientSocket,    
                                              100000 );    
    // 100000 - это таймаут в миллисекундах.
    try
      while ( not Terminated ) and ( ClientSocket.Connected ) do    
      try
      if ( not Terminated ) and    
   ( not fSocketStream.WaitForData( 1000000 ) ) then    
begin
  Form1.Memo1.Lines.Add(Form1.ServerSocket1.Socket.ReceiveText);
end;

      except on e:exception do    
        begin
        Form1.Memo1.Lines.Add('Error');
          // Если произошла ошибка, то закрываем сокет и выходим
          ClientSocket.Close;
          Terminate;
        end;    
      end;
    finally
      fSocketStream.Free;
    end;
  except on e:exception do
    begin
      // Если произошла ошибка, то закрываем сокет и выходим
      ClientSocket.Close;
      Terminate;
    end;
  end;
end;
end.


однако в мемо ничего не выводится, точнее выводится, но только строка по событию OnDisconnect, тоесть событие OnConnect даже не срабатывает...
Может я что-то делаю не так?

Код основной программы

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, unit2;

type
  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
    Memo1: TMemo;
    procedure ServerSocket1GetThread(Sender: TObject;
      ClientSocket: TServerClientWinSocket;
      var SocketThread: TServerClientThread);
    procedure ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.ServerSocket1.Open;
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Form1.Memo1.Lines.Add('conn');
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Form1.Memo1.Lines.Add('disconn');
end;

procedure TForm1.ServerSocket1GetThread(Sender: TObject;
  ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread);
begin
SocketThread := TServerThread.Create( FALSE, ClientSocket );
end;

end.


Перерыл весь поиск и FAQ, но везде написано одно и то же....и в общем ничего толкового...
Заранее спасибо...

Автор: Romikgy 28.3.2006, 15:26
А разве не в
Цитата(NoliX @ 28.3.2006, 13:59 Найти цитируемый пост)
ServerSocket1ClientConnect

надо создавать поток?

Автор: NoliX 28.3.2006, 15:30
Честно говоря понятия не имею =), но в DRKB написано
Код

Устанавливаем следующий код на OnSocketGetThread

Добавлено @ 15:40
да, действительно не работает на ServerSocket1ClientConnect, ругается на SocketThread и ClientSocket

Автор: NoliX 28.3.2006, 16:23
Нигде нет нормальной документации по сокетамна русском языке =(((
везде бесполезные отрывки....

Автор: Romikgy 28.3.2006, 16:35
Цитата(NoliX @ 28.3.2006, 14:30 Найти цитируемый пост)
, ругается на SocketThread и ClientSocket

их там нет это локальные переменые для ServerSocket1GetThread
одно непонятно как может вызватся


Цитата(NoliX @ 28.3.2006, 13:59 Найти цитируемый пост)
OnDisconnect

без
Цитата(NoliX @ 28.3.2006, 13:59 Найти цитируемый пост)
OnConnect

Где код клиента? или чем тестируешь свой сервер?

Автор: NoliX 28.3.2006, 16:48
Код клиента просто до безобразия:
Код

ClientSocket1.Socket.SendText('Hello');

Автор: NoliX 28.3.2006, 17:04
Товарищи, дайте пожалуйста нормальный, рабочий пример, свзи нескольких клиентов с сервером, где каждому клиенту сопоставляется отдельный поток....

То что лежит в drkb - это бред... =(

Автор: Romikgy 28.3.2006, 17:11
Цитата(NoliX @ 28.3.2006, 16:04 Найти цитируемый пост)
То что лежит в drkb - это бред... =(

дома проверю

PS а че не юзаешь индейцев?

Автор: NoliX 28.3.2006, 17:16
хмм, надо попробывать, а с ними проще?

Автор: N1k 28.3.2006, 17:44
NoliX, Тяжело понять что ты хочешь.
Может это:
Код

unit Unit2;

interface
uses
  Classes,ScktComp;

type
  TClThread = class(TThread)
  private
    FSocket: TCustomWinSocket;
    procedure SetSocket(const Value: TCustomWinSocket);
    procedure ClEvent(Sender: TObject; Socket: TCustomWinSocket;
        SocketEvent: TSocketEvent);
    procedure ClError(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
  protected
    procedure Execute; override;
  public
    constructor Create;
    property Client:TCustomWinSocket read FSocket write SetSocket;
  end;

implementation

procedure TClThread.ClError(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
Terminate;
end;

procedure TClThread.ClEvent(Sender: TObject; Socket: TCustomWinSocket;
  SocketEvent: TSocketEvent);
begin
if SocketEvent = seDisconnect then Terminate;
end;

constructor TClThread.Create;
begin
inherited Create(true);
end;

procedure TClThread.Execute;
begin
FreeOnTerminate:=true;
while not Terminated do;
end;

procedure TClThread.SetSocket(const Value: TCustomWinSocket);
begin
  FSocket := Value;
  FSocket.OnSocketEvent:=ClEvent;
  FSocket.OnErrorEvent:=ClError;
end;

end.


Код

...
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
with TClThread.create do
   Client:=Socket;
end;
...

Незнаю насколько это правильно.

Автор: NoliX 29.3.2006, 11:10
не работает корректно...

Автор: N1k 29.3.2006, 13:28
Цитата(NoliX @ 29.3.2006, 11:10 Найти цитируемый пост)
не работает корректно...

Конечно не корректно, что б заставить корректно работать нужно над этим еще поработать(во загнул smile ).
Например самому удалять отключившегося клиента из активных соединений.
Не пойму зачем тебе все это надо, и так все работает в потоке.

зы:А что не корректно?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)