Форум: "Сети";
Текущий архив: 2003.03.10;
Скачать: [xml.tar.bz2];
ВнизПро поток и TServerSocket... Найти похожие ветки
← →
nikulin (2003-01-22 13:28) [0]Создаю в потоке обьект TServerSocket.
Затем собственно уничтожаю его в деструкторе Destroy потока.
Но когда переключаю фокус с формы то выскакивает ошибка
Access violation at address 00000000. Read of address 00000000.
При этом если закоментировать код который в конструкторе присваевает обьекту номер порта и открывает сокет, то никакой ошибки не происходит.
Может кто подскажет в чем проблема?
Создаю поток вот так
FollowMeThread := TFM.Create(True);
*****************************************************
unit FMThrd;
interface
uses
Classes, SysUtils, ScktComp;
const
ConnectString = "Provider=SQLOLEDB.1;" +
"Integrated Security=SSPI;" +
"Persist Security Info=False;" +
"Initial Catalog=Abonent;Data Source=cops";
type
TFM = class(TThread)
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
private
{ Private declarations }
FIP: ShortString;
FPort: Word;
FLastCmdAnswer: String;
FCMDState: (stAdded, stExec, stOk, stError, stTimeOut, stNone);
FServerSocket: TServerSocket;
procedure ClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ServerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
protected
procedure Execute; override;
end;
implementation
constructor TFM.Create(CreateSuspended: Boolean);
begin
inherited Create(True);
Priority := tpNormal;
FreeOnTerminate := True;
try
FServerSocket := TServerSocket.Create(nil);
FServerSocket.OnClientRead := ClientRead;
FServerSocket.OnClientError := ServerSocketClientError;
FServerSocket.OnClientConnect := ClientConnect;
except
end;
{*************************************}
//если это закоментировать то все ок
FPort := 2000;
FServerSocket.Port := FPort;
repeat
try
FServerSocket.Open;
except
if FServerSocket.Active then
FServerSocket.Close;
FPort := FPort + 1;
FServerSocket.Port := FPort;
end;
until FServerSocket.Active;
{*************************************}
Resume;
end;
destructor TFM.Destroy;
begin
FServerSocket.Active := False;
FServerSocket.Free;
end;
procedure TFM.Execute;
var
x,q,z: Integer;
begin
z:=x+q;
if z = 10 then x:= q;
end;
procedure TFM.ServerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
FCMDState := stError;
end;
procedure TFM.ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
//
end;
procedure TFM.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
rec_str: String;
begin
rec_str := Socket.ReceiveText;
end;
end.
← →
REA (2003-01-22 13:35) [1]Честно говоря не понимаю зачем в потоке создавать сервер, который тоже создает поток (да еще менять ему порт). Потом все эти штучки с Active и Close не сразу проходят (по крайней мере для клиента). Вобщем не понял я зачем все это нужно.
← →
nikulin (2003-01-22 13:44) [2]Пояснение.
Создавать сервер в потоке надо затем что поток создается для выполнения несколько специфической задачи. В процессе выполнения задачки к TCP-серверу законектится клиентик и отдаст ему кое-какие данные. Так как клиент коннектится по своему усмотрению поэтому и нужет сервер. Ведь он ОЖИДАЕТ коннекта клиента.
Поток нужен для распараллеливания задачи. Порт меняю так как на локальной машине порт уже может быть занят другим потоком или вообще процессом.
← →
Digitman (2003-01-22 13:48) [3]серверный объект ты создаешь отнюдь не в доп.потоке, а в том, который вызвал конструктор класса TFM !
а это что за белиберда ? что тут творится у тебя ? комментируй ...
procedure TFM.Execute;
var
x,q,z: Integer;
begin
z:=x+q;
if z = 10 then x:= q;
end;
в этой процедуре как раз и должны быть действия, предусмотренные тобой для исполнения в доп.код.потоке !
← →
REA (2003-01-22 13:58) [4]Сервер понятно для чего нужен, но непонятно что за специфическая задача создавать еще один поток для сервера, кроме тех потоков, которые он создает сам.
← →
nikulin (2003-01-22 14:00) [5]2 Digitman.
Код в методе Execute просто для того чтобы войти в него в отладчике. На самом деле там дальше будет много чего.
Смысл в том что я создаю в потоке TCP сервер открываю его для прослушивания порта. Затем уничтожаю и получаю ошибку.
Я пробовал когда у меня в методе Execute работал нормальны код. И вся моя логика работала. Но выскакивала эта ошибка. Начал искать в чем проблема. Поэтому и спрашивал в форуме про обьекты ADO и тд. В конце концов докапался что ошибка происходит или связана с сервером.
И в чем проблема не знаю.
← →
nikulin (2003-01-22 14:08) [6]Прикол вот в чем. Создаю поток. В потоке открываю TCP-сервер на прослушивание какого-то порта. Затем даю некое задание другой программе(просто помещаю задание и координаты сервера IP и порт в БД). Другаю программа выбирает задание из БД, выполняет его и по координатам сервера отправляет ответ.
Поток в первой проге получив ответ или отвалившись по таймауту ожидания ответа завершает свою работу. И освобождает свои ресурсы.
Потоков может быть несколько.
← →
nikulin (2003-01-22 14:44) [7]---------------------------
Error
---------------------------
Runtime error 216 at 0044BFF4
---------------------------
OK
---------------------------
А как найти по номеру ошибки описание?
← →
Smithson (2003-01-22 14:50) [8]Методу создания сервера попробуй сделать Synchronize
← →
nikulin (2003-01-22 14:52) [9]А с событиями OnClientRead, OnClientError и тд как быть?
← →
nikulin (2003-01-22 15:13) [10]2 All.
НАШЕЛЛЛЛЛ!!!!! УРААА!!!!
перенес код открытия порта из конструктора в метод Execute. Вудь получалось что создается TCP-сервер, открывается порт. При этом начинает работу поток самого обьекта TCP-сервера, в то время когда основной поток находится в состоянии Suspended!!!!
Ну в результате все сыпится!!
2 Digitman Если у Вас есть более ПОЛНОЕ обьямнение то очень буду вам признателен за него.
Всем спасибо огромное!!!!
← →
Digitman (2003-01-22 15:27) [11]
> nikulin
фигней ты, сударь, занимаешься, скажу я тебе)
Нет никакого резона помешать конструирование и работу с TServerSocket в доп.код.поток. Ничем это не оправдано абсолютно.
В доп.код.потоки следует поместить транспортные алгоритмы для каждого из будущих кл.соединений. Дляы этой цели в классе TServerSocket предусмотрено cв-во ServerType = stThreadBlocking и событие OnGetThread. При stThreadBlocking в момент необходимости организации нового трансп.код.потока для нового отдельного соединения с клиентом сервер сам спросит тебя о том, хочешь ли ты применить для этой цели новый объект класса TServerClientThread с собственной реализацией транспорта. Все. что от тебя требуется - отреагировать на событие OnGetThread должным образом : создать объект-наследник TServerClientThread в обработчике этого события и вернуть ссылку на него в параметре ClientThread
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2003.03.10;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.01 c