Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 26.12.2013, 16:57
alanatolich alanatolich вне форума
Прохожий
 
Регистрация: 24.12.2013
Сообщения: 18
Версия Delphi: Delphi XE
Репутация: 10
По умолчанию динамическое создание сокетов в потоке

Помогите при компиляции, выдает ошибку на строчку.

Код:
MYClientSocket.OnRead:=ClientSocketRead;

[DCC Error] mypotok.pas(81): E2009 Incompatible types: 'method pointer and regular procedure'

Как правильно обработать события от созданных сокетах?




Код:
unit mypotok;

interface

uses
  ScktComp,
  Classes,SysUtils, ADODB,ActiveX;
  
    // данные из сокета
    procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
type
  TMyThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;


var MYClientSocket:TClientSocket;

implementation


procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
begin
	{}
end;

procedure TMyThread.Execute;
var termial:TStringList;
  I: Integer;
    myList:TList;
const NumberClientSocket=1;

begin
    // создаем список
    MYList := TList.Create;
    // создаем сокеты
    for I :=0 to NumberClientSocket do
    begin
        MYClientSocket:=TClientSocket.Create(nil);
        MYClientSocket.OnRead:=ClientSocketRead;
        MYClientSocket.Name:='MS'+inttostr(I);
        MYList.Add(MYClientSocket);
    end;
    // основной цикл потока
    while True do
    begin
        TClientSocket(myList[i]).Address:=terminalip('127.0.0.1');
        TClientSocket(myList[i]).port:=55555;
        TClientSocket(myList[i]).Open;
    end;
    // освобождаем сокеты
    for I :=0 to NumberClientSocket do
    begin
        TClientSocket(myList[i]).Close;
        TClientSocket(myList[i]).Free;
    end;
    // освобождаем список
    termial.Free;
end;

end.

Последний раз редактировалось alanatolich, 26.12.2013 в 17:35.
Ответить с цитированием
  #2  
Старый 26.12.2013, 17:46
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

1. метод ClientSocketRead должен быть методом класса потока
2. более важное. а зачем использовать асинхронный (неблокируемый) сокет в потоке?
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #3  
Старый 27.12.2013, 09:31
alanatolich alanatolich вне форума
Прохожий
 
Регистрация: 24.12.2013
Сообщения: 18
Версия Delphi: Delphi XE
Репутация: 10
По умолчанию

Переделал, но все равно выдает ошибку.

[DCC Error] mypotok.pas(16): E2065 Unsatisfied forward or external declaration: 'TMyThread.ClientSocketRead'

на строку

Код:
    procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);

Приведите пожалуйста пример как правильно.

Код:
unit mypotok;

interface

uses
  ScktComp,
  Classes,SysUtils, ADODB,ActiveX;

type
  TMyThread = class(TThread)

    // данные из сокета
    procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);

  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;


var MYClientSocket:TClientSocket;

implementation


procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
begin

end;

procedure TMyThread.Execute;
var termial:TStringList;
  I: Integer;
    myList:TList;
const NumberClientSocket=1;

begin
    // создаем список
    MYList := TList.Create;
    // получаем список терминалов на загрузки
    termial:=terminals('loading');
    //
    // создаем сокеты
    for I :=0 to NumberClientSocket do
    begin
        MYClientSocket:=TClientSocket.Create(nil);
        MYClientSocket.OnRead:=ClientSocketRead;
        MYClientSocket.Name:='MS'+inttostr(I);
        MYList.Add(MYClientSocket);
    end;
    // основной цикл потока
    while True do
    begin
        TClientSocket(myList[0]).Address:=terminalip('127.0.0.1');
        TClientSocket(myList[0]).port:=55555;
        TClientSocket(myList[0]).Open;
    end;
    // освобождаем сокеты
    for I :=0 to NumberClientSocket do
    begin
        TClientSocket(myList[i]).Close;
        TClientSocket(myList[i]).Free;
    end;
    // освобождаем список
    termial.Free;
end;

end.

Расскажите что представляют из себя асинхронный (неблокируемый)/синхронный (блокируемый) сокет.

Расскажите в чем разница использования асинхронный (неблокируемый)/синхронный (блокируемый) сокет.

Почему не правильно использовать асинхронный (неблокируемый) сокет в потоке?

За информацию буду очень благодарен
Ответить с цитированием
  #4  
Старый 27.12.2013, 09:50
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Цитата:
Сообщение от alanatolich
Переделал, но все равно выдает ошибку.

[DCC Error] mypotok.pas(16): E2065 Unsatisfied forward or external declaration: 'TMyThread.ClientSocketRead'
Тебе надо переписать объявление процедуры ниже по коду. Метод класса должен "раскрываться" как-то так:
Код:
procedure TMyThread.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
begin
end;
Цитата:
Расскажите что представляют из себя асинхронный (неблокируемый)/синхронный (блокируемый) сокет. Расскажите в чем разница использования асинхронный (неблокируемый)/синхронный (блокируемый) сокет. Почему не правильно использовать асинхронный (неблокируемый) сокет в потоке?
Всё просто. Синхронный выполняется в одном потоке с программой, что приводит к тому, что при работе с этим сокетом программа "подвисает". Оно и понятно - пока не отработает часть с сокетами, для самой программы ресурсов выделять никто не будет.
В случае с асинхронными сокетами сразу выделяется отдельный поток, в котором работает вся сетевая часть. А взаимодействие с программой происходит через вызовы т.н. "каллбэков", которые (при правильном построении кода) совершенно не мешают основной программе. Именно поэтому использование асинхронных сокетов в потоке не то, что бы "неправильно", а просто бессмысленно...
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
Этот пользователь сказал Спасибо PhoeniX за это полезное сообщение:
alanatolich (27.12.2013)
  #5  
Старый 27.12.2013, 10:21
alanatolich alanatolich вне форума
Прохожий
 
Регистрация: 24.12.2013
Сообщения: 18
Версия Delphi: Delphi XE
Репутация: 10
По умолчанию

Я в программе планирую отправлять/принимать данные на N-е количество компьютеров, через сокеты.
В основном цикле патока должны постоянно формироваться разные данные, для каждого удаленного компьютера, и отправляться через сокеты, причем разные объемы данных, для разных компьютеров.
То есть основной цикл потока будет готовить данные и распихивать порции данных по сокетам, а сокеты будут отправлять и получать данные с удаленных компьютеров.

Надеюсь понятно изложил.

В данном случаи асинхронные сокеты более подойдут?
Ответить с цитированием
  #6  
Старый 27.12.2013, 10:38
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Цитата:
Сообщение от alanatolich
В данном случаи асинхронные сокеты более подойдут?
легко.....
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #7  
Старый 30.12.2013, 17:56
alanatolich alanatolich вне форума
Прохожий
 
Регистрация: 24.12.2013
Сообщения: 18
Версия Delphi: Delphi XE
Репутация: 10
По умолчанию

Эх, опять не хочет компилироваться

Код:
unit mypotok;

interface

uses
  ScktComp,
  Classes,SysUtils, ADODB,ActiveX;

type
  TMyThread = class(TThread)

    // данные из сокета
    procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
    // соеденение
    procedure ClientSocketConnect(Sender: TObject;  Socket: TCustomWinSocket);
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;


var MYClientSocket:TClientSocket;

implementation

uses unit1;

procedure TMyThread.ClientSocketConnect(Sender: TObject;  Socket: TCustomWinSocket);
begin
    Socket.SendText('test ');
end;
procedure TMyThread.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
begin

end;

procedure TMyThread.Execute;
  I: Integer;
    myList:TList;
const NumberClientSocket=1;

begin
    // создаем список
    MYList := TList.Create;
    // создаем сокеты
    for I :=0 to NumberClientSocket do
    begin
        MYClientSocket:=TClientSocket.Create(nil);
        MYClientSocket.OnRead:=TMyThread.ClientSocketRead;
        MYClientSocket.OnConnect:=TMyThread.ClientSocketConnect;
        MYClientSocket.Name:='MS'+inttostr(I);
        MYList.Add(MYClientSocket);
    end;
    // прописываем IP сокету последнего терминала в списке
    TClientSocket(myList[0]).Address:=terminalip(termial[termial.Count-1-I]);
    // прописываем порт
    TClientSocket(myList[0]).port:=55555;
    // соеденяемся
    TClientSocket(myList[0]).Open;
		
    while True do
    begin 
    end;
    // освобождаем сокеты
    for I :=0 to NumberClientSocket do
    begin
        TClientSocket(myList[i]).Close;
        TClientSocket(myList[i]).Free;
    end;
    // освобождаем список
    termial.Free;
end;

end.

ошибка на строчках

Код:
MYClientSocket.OnRead:=TMyThread.ClientSocketRead;
Код:
MYClientSocket.OnConnect:=TMyThread.ClientSocketConnect;

[DCC Error] mypotok.pas(111): E2010 Incompatible types: 'TSocketNotifyEvent' and 'Procedure'
[DCC Error] mypotok.pas(112): E2010 Incompatible types: 'TSocketNotifyEvent' and 'Procedure'

Как правильно присвоить обработчики?
Ответить с цитированием
  #8  
Старый 30.12.2013, 18:11
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от alanatolich
ошибка на строчках

Код:
MYClientSocket.OnRead:=TMyThread.ClientSocketRead;
Код:
MYClientSocket.OnConnect:=TMyThread.ClientSocketConnect;

[DCC Error] mypotok.pas(111): E2010 Incompatible types: 'TSocketNotifyEvent' and 'Procedure'
[DCC Error] mypotok.pas(112): E2010 Incompatible types: 'TSocketNotifyEvent' and 'Procedure'

Как правильно присвоить обработчики?
Нужно не через класс, а через объект. В данном случае просто убери в этих строчках "TMyThread.".
Ответить с цитированием
  #9  
Старый 31.12.2013, 09:13
alanatolich alanatolich вне форума
Прохожий
 
Регистрация: 24.12.2013
Сообщения: 18
Версия Delphi: Delphi XE
Репутация: 10
По умолчанию

Цитата:
Нужно не через класс, а через объект. В данном случае просто убери в этих строчках "TMyThread.".
Убрать пробовал, компилируется , но обработчик

Код:
procedure TMyThread.ClientSocketConnect(Sender: TObject;  Socket: TCustomWinSocket);
begin
    Socket.SendText('test ');
end;
не отрабатывает в чем причина не пойму
Ответить с цитированием
  #10  
Старый 31.12.2013, 12:45
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от alanatolich
Убрать пробовал, компилируется , но обработчик

Код:
procedure TMyThread.ClientSocketConnect(Sender: TObject;  Socket: TCustomWinSocket);
begin
    Socket.SendText('test ');
end;
не отрабатывает в чем причина не пойму
Событие то происходит (наверное), но не обрабатывается, так как у тебя в потоке вместо обработки сообщений стоит "глухой цикл":
Код:
    while True do
    begin
    end;
В отдельном потоке сообщения нужно обрабатывать самостоятельно:
Код:
procedure TMyThread.Execute;
.....
var
  Msg: TMsg;
begin
.....
  // создаем сокеты
.....
  while not Terminated do
  begin
    if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
    begin
      TranslateMessage(Msg);
      DispatchMessage(Msg);
    end;
  end;
.....
  // освобождаем сокеты
.....
end;
Ответить с цитированием
  #11  
Старый 09.01.2014, 15:57
alanatolich alanatolich вне форума
Прохожий
 
Регистрация: 24.12.2013
Сообщения: 18
Версия Delphi: Delphi XE
Репутация: 10
По умолчанию

poli-smen большое спасибо.
добавил в цикл

Код:
    if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
    begin
      TranslateMessage(Msg);
      DispatchMessage(Msg);
    end;

все заработало.

Объясните пожалуйста эти три процедуры

Код:
PeekMessage
TranslateMessage
DispatchMessage

PeekMessage - я понял, что она проверяет есть ли в очереди сообщение, а вот две другие, не понял, за объяснение буду очень благодарен
Ответить с цитированием
  #12  
Старый 09.01.2014, 16:23
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от alanatolich
Объясните пожалуйста эти три процедуры

Код:
PeekMessage
TranslateMessage
DispatchMessage

PeekMessage - я понял, что она проверяет есть ли в очереди сообщение, а вот две другие, не понял, за объяснение буду очень благодарен
Это стандартный цикл обработки сообщений. Впрочем да, так как у тебя в потоке нажатия клавиш не нужно обрабатывать, то TranslateMessage можно убрать. А DispatchMessage собственно и передаёт извлечённое из очереди сообщение на обработку в оконную процедуру. Ещё здесь неплохо бы сделать также небольшую задержку чтобы не сильно грузить процессор в холостом цикле.
Вот новый вариант цикла обработки сообщений:
Код:
    while not Terminated do
    begin
      if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then DispatchMessage(Msg) else Sleep(100);
    end;
Ответить с цитированием
  #13  
Старый 09.01.2014, 17:11
alanatolich alanatolich вне форума
Прохожий
 
Регистрация: 24.12.2013
Сообщения: 18
Версия Delphi: Delphi XE
Репутация: 10
По умолчанию

poli-smen

Вот интересный момент
Цитата:
А DispatchMessage собственно и передаёт извлечённое из очереди сообщение на обработку в оконную процедуру.

у меня приложение без оконное (служба), запускающее отдельный поток работы с сокетами.

Я не верно что то понимаю, что имеется в виду под словами оконная процедура
Ответить с цитированием
  #14  
Старый 09.01.2014, 17:27
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от alanatolich
poli-smen

Вот интересный момент


у меня приложение без оконное (служба), запускающее отдельный поток работы с сокетами.

Я не верно что то понимаю, что имеется в виду под словами оконная процедура
В классе TCustomWinSocket создаётся невидимое окно, которое и принимает на себя сообщения от сокета.
Вот в этом куске кода из стандартного модуля ScktComp и создаётся это окно:
Код:
function TCustomWinSocket.GetHandle: HWnd;
begin
  if FHandle = 0 then
    FHandle := AllocateHwnd(WndProc);
  Result := FHandle;
end;
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
alanatolich (09.01.2014)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 06:27.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025