![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
От чего возникает ошибка [D7, XP]
KyRo © (2006-05-10 13:01:00)У меня есть сервер и клиент которые работают в блокирующем режиме.
Я передаю строку от клиента к серверу , сервер ее получает в перекрытом методе ClientExecute и сразу после этого возникает "ошибка доступа к памяти и адрес памяти"
Вот код отправки сообщения
if Client.Socket.Connected then
Client.Socket.SendText('AAA');
Вот так я принимаю на сервере
procedure TClientThread.ClientExecute;
begin
s:=ClientSocket.ReceiveText;
end;
Может я не свобождаю память или нити или из за чего это вообще может быть ?
Пусик (2006-05-10 19:45:00) [1]Удалено модератором
Шпиён (2006-05-10 19:45:00) [2]
> Сергей М. © (10.05.06 14:15) [10]
>
> > тут я его принимаю и присваиваю глобальной переменной
> значение
> > 1
>
>
> Ты здоров, братец ?
>
> Ты только что записал в переменную s что-то там переданное
> рередатчиком сообщения..
А переменная s в данном конкретном случае к AV никакого отношения не имеет.
Пусик (2006-05-10 19:38:00) [3]
> KyRo
У тебя в принципе реализовано неверно.
Смотри пример.
Код клиента:
TForm1 = class(TForm)
cs: TClientSocket;
ss: TServerSocket;
pb: TProgressBar;
procedure TForm1.csConnect(Sender: TObject; Socket: TCustomWinSocket);
var
Buf: array[0..8191] of Char;
Readed: Int64;
Writed: Int64;
begin
FS := TFileStream.Create('D:\apps\VPC\DOS.ZIP',fmOpenRead);
pb.Min := 0;
pb.Max := FS.Size;
pb.Tag := Trunc(FS.Size/100);
Memo1.Lines.Add('Connected to '+Socket.RemoteAddress);
end;
procedure TForm1.csWrite(Sender: TObject; Socket: TCustomWinSocket);
var
Buf: array[0..BUF_LEN-1] of Char;
Readed: Int64;
Writed: Int64;
begin
if pb.Position=0 then
begin
Memo1.Lines.Add('Send File Size - '+FormatFloat('#,##0',FS.Size)+' bytes');
Writed := FS.Size;
Socket.SendBuf(Writed,8);
Memo1.Lines.Add('Start send File');
end;
while pb.Position<=pb.Max do
begin
Application.ProcessMessages;
Readed := FS.Read(Buf[0],BUF_LEN);
if Readed=0 then
begin
pb.Position := FS.Position;
Memo1.Lines[Memo1.Lines.Count-1] := 'Transferred '+ FormatFloat('#,##0',pb.Position)+' bytes';
cs.Close;
Exit;
end;
Writed := Socket.SendBuf(Buf[0],Readed);
if Writed=-1 then
begin
Label1.Caption := IntToStr(StrToInt(Label1.Caption)+1);
FS.Position := FS.Position-Readed;
Exit;
end;
if Writed<Readed then FS.Position := FS.Position-Readed+Writed;
pb.Position := FS.Position;
if pb.Position>pb.Tag then
begin
pb.Tag := pb.Tag+Trunc(FS.Size/100);
Memo1.Lines[Memo1.Lines.Count-1] := 'Transferred '+ FormatFloat('#,##0',pb.Position)+' bytes';
end;
end;
end;
Здесь PB - TProgressBar
Серверная часть:
type
TThrSock=class(TServerClientThread)
private
FStream: TWinSocketStream;
FTime,FLastTime: Cardinal;
function CheckTimeOut: Boolean;
public
constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
destructor Destroy; override;
procedure ClientExecute; override;
end;
var
Form1: TForm1;
FS: TFileStream;
constructor TThrSock.Create(CreateSuspended: Boolean;
ASocket: TServerClientWinSocket);
begin
inherited Create(True,ASocket);
FreeOnTerminate := True;
FTime := 5000;
Resume;
end;
destructor TThrSock.Destroy;
begin
Form1.Memo1.Lines.Add('DestroyThread');
inherited;
end;
procedure TForm1.ssClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Socket.Data := nil;
end;
procedure TForm1.ssGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread := TThrSock.Create(False,ClientSocket);
Memo1.Lines.Add('CreateThread');
end;
procedure TThrSock.ClientExecute;
var
Buf: array[0..BUF_LEN-1] of Char;
Len: Integer;
FirstREad: Boolean;
begin
FirstRead := True;
FStream := TWinSocketStream.Create(ClientSocket, 5000);
try
while (not Terminated) and (ClientSocket.Connected) do
begin
if not FStream.WaitForData(1000) then Continue;
Len := FStream.Read(Buf[0],BUF_LEN);
if FirstRead then
begin
if Len>7 then
begin
FS := TFileStream.Create('TestFile.tst',fmCreate);
FS.Write(Buf[8],Len-8);
FirstRead := False;
end;
end
else FS.Write(Buf[0],Len);
if Len=0 then
begin
FS.Free;
Terminate;
ClientSocket.Close;
Exit;
end;
end;
finally
FStream.Free;
end;
end;
Код рабочий, для проверки в обработчики на сервере добавлен непотокобезопасный код - работа с TMemo.
Может быть лишний код, так как выдрано из тестого проекта.
Шпиён (2006-05-10 19:30:00) [4]1) Код страшный...
2) Причина Accees Violation :
Procedure TServerHr.GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
// ClientThread - вот оно !!!
// исправим:
SocketThread:=TClientThread.Create(False,ClientSocket);
end;
Доказательство:
Если посмотреть на исходник ScktComp, видим:
function TServerWinSocket.GetServerThread(ClientSocket: TServerClientWinSocket): TServerClientThread;
var
I: Integer;
begin
Result := nil;
FListLock.Enter;
try
for I := 0 to FActiveThreads.Count - 1 do
if TServerClientThread(FActiveThreads[I]).ClientSocket = nil then
begin
Result := FActiveThreads[I];
Result.ReActivate(ClientSocket);
Break;
end;
finally
FListLock.Leave;
end;
if Result = nil then
begin
if Assigned(FOnGetThread) then FOnGetThread(Self, ClientSocket, Result);
if Result = nil then Result := DoCreateThread(ClientSocket);
end;
end;
KyRo (2006-05-10 16:29:00) [5]Удалено модератором
Примечание: Нападки, грубость
Сергей М. (2006-05-10 16:24:00) [6]
> Ты покажи где кто мне что привел
Галиматья.
Изволь ответить на предыдущую галиматью
> Не Finally перекрыть а в TServerClientThread метод Execute
> > потому что эта
KyRo (2006-05-10 15:49:00) [7]Удалено модератором
Сергей М. (2006-05-10 15:38:00) [8]Удалено модератором
KyRo (2006-05-10 15:33:00) [9]Хорошо из за чего она тогда может быть ?
Сергей М. (2006-05-10 15:30:00) [10]
> KyRo (10.05.06 15:18) [14]
>
> Не Finally перекрыть а в TServerClientThread метод Execute
> потому что эта ошибка возникает как раз после выполнения
> метода
> ClientxEcute который и вызывается из метода Execute
>
>
> procedure TServerClientThread.Execute;
> begin
> FServerSocket.ThreadStart(Self);
Галиматьища несусветная ..
KyRo (2006-05-10 15:18:00) [11]Не Finally перекрыть а в TServerClientThread метод Execute
потому что эта ошибка возникает как раз после выполнения метода
ClientxEcute который и вызывается из метода Execute
procedure TServerClientThread.Execute;
begin
FServerSocket.ThreadStart(Self);
try
try
while True do
begin
if StartConnect then ClientExecute;
if EndConnect then Break;
end;
except
HandleException;
KeepInCache := False;
end;
finally
FServerSocket.ThreadEnd(Self);
end;
end;
Я просто не вижу где где происходит эта ошибка и мне интересно поможет ли это ?
balepa (2006-05-10 14:47:00) [12]Удалено модератором
Сергей М. (2006-05-10 14:39:00) [13]Извини, умываю руки.
Видимо, я туп.
> розделе Finally ..перекрыть
Эта фраза выше моего понимания.
KyRo (2006-05-10 14:35:00) [14]
> Ты здоров, братец ?
>
> Ты только что записал в переменную s что-то там переданное
> рередатчиком сообщения..
Нет на єто не обращай внимания это я просто так написал , я прикрасно понимаю что я перезаписываю сообщение которое пришло.
Эту строчку можно убрать , а поставил я ее что бы споймать ошибку , я не могу понять где именно она происходит и мне кажется что в розделе Finally метода TServerClientThread
Может его стоит перекрыть ?
Сергей М. (2006-05-10 14:15:00) [15]
> тут я его принимаю и присваиваю глобальной переменной значение
> 1
Ты здоров, братец ?
Ты только чтозаписал в переменную sчто-то там переданное рередатчиком сообщения..
KyRo (2006-05-10 13:43:00) [16]
> balepa © (10.05.06 13:41) [8]
>
> > KyRo (10.05.06 13:36) [6]
> > В идеале мне надо от клиента передать файл серверу.
>
> А файл тоже строками передавать будеш ?
Нет файл передам потоком. Просто я не когда раньше не писал приложения работающие с сетью , по этому я пока тока разбираюсь и пробую .
balepa (2006-05-10 13:41:00) [17]
> KyRo (10.05.06 13:36) [6]
> В идеале мне надо от клиента передать файл серверу.
А файл тоже строками передавать будеш ?
KyRo (2006-05-10 13:39:00) [18]
> Сергей М. © (10.05.06 13:30) [4]
> И заодно объясни, накой шут тебе мультипоточность..
Мультипоточность потому что потом этот сервер и клиент будут запускатся как потоки сервисов.
KyRo (2006-05-10 13:36:00) [19]В идеале мне надо от клиента передать файл серверу.
В данный момент мне нужно для начала передать хотя бы текст
procedure TClientThread.ClientExecute;
>
> begin
> s:=ClientSocket.ReceiveText;
> s:='1';
И вот тут я его принимаю и присваиваю глобальной переменной значение 1
для того что бы завершить работу нити и выключить сервер
While (not Terminated)and(s<>'1') do
begin
end;
Server.Active:=False;
Server.Free;
Так вот эта ошибка появляется до того как происходит
Server.Active:=False;
То есть как я понимаю она может возникать где то в классе TServerClientThread
balepa (2006-05-10 13:33:00) [20]
> KyRo (10.05.06 13:14) [2]
> В них есть лишние методы которые не работают в блокирующем
> режиме их я потом уберу.
Еще бы со всег прог накидал код который не нужен, чужой траффик не жалеем совсем.