Форум: "Начинающим";
Текущий архив: 2006.05.28;
Скачать: [xml.tar.bz2];
ВнизОт чего возникает ошибка Найти похожие ветки
← →
KyRo (2006-05-10 13:01) [0]У меня есть сервер и клиент которые работают в блокирующем режиме.
Я передаю строку от клиента к серверу , сервер ее получает в перекрытом методе ClientExecute и сразу после этого возникает "ошибка доступа к памяти и адрес памяти"
Вот код отправки сообщения
if Client.Socket.Connected then
Client.Socket.SendText("AAA");
Вот так я принимаю на сервере
procedure TClientThread.ClientExecute;
begin
s:=ClientSocket.ReceiveText;
end;
Может я не свобождаю память или нити или из за чего это вообще может быть ?
← →
Сергей М. © (2006-05-10 13:04) [1]Судя по этим огрызкам кода все что угодно может быть.
И пока ты будешь практиковать цитирование своих "огрызков" (не в первый раз уже замечено это), реальную помощь ты вряд ли получишь.
← →
KyRo (2006-05-10 13:14) [2]
> Судя по этим огрызкам кода все что угодно может быть.
В том то и дело что кроме них вообщем то не чего нет !!!
Если полностью то вот полностью клиент
unit NetworkClientHR;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,ScktComp;
type
TNetwork_ClientHR = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
constructor Create(CreateSuspennded: Boolean);
procedure ClientRead(Sender: TObject;Socket: TCustomWinSocket);
procedure ClientWrite(Sender: TObject;Socket: TCustomWinSocket);
end;
implementation
Procedure TNetwork_ClientHR.ClientRead(Sender: TObject;Socket: TCustomWinSocket);
begin
end;
Procedure TNetwork_ClientHR.ClientWrite(Sender: TObject;Socket: TCustomWinSocket);
begin
end;
constructor TNetwork_ClientHR.Create(CreateSuspennded: Boolean);
begin
inherited Create(CreateSuspennded) ;
Resume;
end;
procedure TNetwork_ClientHR.Execute;
var
Client:TClientSocket;
i:integer;
s:String;
begin
Client:=TClientSocket.Create(nil);
Client.Port:=9990;
Client.HOST:="localhost";
Client.OnRead:=ClientRead;
Client.OnWrite:=ClientWrite;
Client.ClientType:=ctBlocking;
Client.Active:=True;
if Client.Socket.Connected
then
Client.Socket.SendText("AAA");
S:="";
While (Not Terminated)and(s="") do
begin
S:=Client.Socket.ReceiveText;
end;
Client.Active:=False;
Client.Free;
end;
end.
А вот полностью модуль сервера
unit NetworkHr;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
ScktComp;
type
TServerHr = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
constructor Create(CreateSuspennded: Boolean);
Procedure GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
procedure ServerClientConnect(Sender: TObject;Socket: TCustomWinSocket);
procedure ClientRead(Sender: TObject;Socket: TCustomWinSocket);
procedure ClientWrite(Sender: TObject;Socket: TCustomWinSocket);
end;
TClientThread = class(TServerClientThread)
private
protected
procedure ClientExecute; override;
public
end;
var
Server:TServerSocket;
ClientThread:TClientThread;
s:string;
implementation
procedure TClientThread.ClientExecute;
begin
s:=ClientSocket.ReceiveText;
s:="1";
end;
Procedure TServerHr.GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
ClientThread:=TClientThread.Create(False,ClientSocket);
end;
constructor TServerHr.Create(CreateSuspennded: Boolean);
begin
inherited Create(CreateSuspennded);
Resume;
end;
procedure TServerHr.ServerClientConnect(Sender: TObject;Socket: TCustomWinSocket);
begin
end;
Procedure TServerHr.ClientRead(Sender: TObject;Socket: TCustomWinSocket);
begin
end;
Procedure TServerHr.ClientWrite(Sender: TObject;Socket: TCustomWinSocket);
begin
end;
procedure TServerHr.Execute;
var
i:integer;
begin
Server:=TServerSocket.Create(nil);
Server.Port:=9990;
Server.ServerType:=stTHreadBlocking;
Server.ThreadCacheSize:=10;
Server.OnGetThread:=GetThread;
Server.OnClientRead:=ClientRead;
Server.OnClientWrite:=ClientWrite;
Server.OnClientConnect:=ServerClientConnect;
Server.Active:=True;
s:="";
While (not Terminated)and(s<>"1") do
begin
end;
Server.Active:=False;
Server.Free;
end;
end.
В них есть лишние методы которые не работают в блокирующем режиме их я потом уберу.
Так вот когда я получаю текст в ClientExecute то все хорошо , а потом как я понимаю после того как все в процедуре отработало и появляется ошибка.
Дословно ошибка Accees Violation at address 00000074
← →
Сергей М. © (2006-05-10 13:29) [3]
> procedure TClientThread.ClientExecute;
>
> begin
> s:=ClientSocket.ReceiveText;
> s:="1";
Ты в состоянии вразумительно объяснить , что ты при этом делаешь ?
И почему переменная s не защищена крит.секцией ?
И вообще - приведи вразумительное описание того чтот тебе требуется реализовать (протокол инф.обмена это называется)
← →
Сергей М. © (2006-05-10 13:30) [4]И заодно объясни, накой шут тебе мультипоточность..
← →
balepa © (2006-05-10 13:33) [5]
> KyRo (10.05.06 13:14) [2]
> В них есть лишние методы которые не работают в блокирующем
> режиме их я потом уберу.
Еще бы со всег прог накидал код который не нужен, чужой траффик не жалеем совсем.
← →
KyRo (2006-05-10 13:36) [6]В идеале мне надо от клиента передать файл серверу.
В данный момент мне нужно для начала передать хотя бы текст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
← →
KyRo (2006-05-10 13:39) [7]
> Сергей М. © (10.05.06 13:30) [4]
> И заодно объясни, накой шут тебе мультипоточность..
Мультипоточность потому что потом этот сервер и клиент будут запускатся как потоки сервисов.
← →
balepa © (2006-05-10 13:41) [8]
> KyRo (10.05.06 13:36) [6]
> В идеале мне надо от клиента передать файл серверу.
А файл тоже строками передавать будеш ?
← →
KyRo (2006-05-10 13:43) [9]
> balepa © (10.05.06 13:41) [8]
>
> > KyRo (10.05.06 13:36) [6]
> > В идеале мне надо от клиента передать файл серверу.
>
> А файл тоже строками передавать будеш ?
Нет файл передам потоком. Просто я не когда раньше не писал приложения работающие с сетью , по этому я пока тока разбираюсь и пробую .
← →
Сергей М. © (2006-05-10 14:15) [10]
> тут я его принимаю и присваиваю глобальной переменной значение
> 1
Ты здоров, братец ?
Ты только что записал в переменную s что-то там переданное рередатчиком сообщения..
← →
KyRo (2006-05-10 14:35) [11]
> Ты здоров, братец ?
>
> Ты только что записал в переменную s что-то там переданное
> рередатчиком сообщения..
Нет на єто не обращай внимания это я просто так написал , я прикрасно понимаю что я перезаписываю сообщение которое пришло.
Эту строчку можно убрать , а поставил я ее что бы споймать ошибку , я не могу понять где именно она происходит и мне кажется что в розделе Finally метода TServerClientThread
Может его стоит перекрыть ?
← →
Сергей М. © (2006-05-10 14:39) [12]Извини, умываю руки.
Видимо, я туп.
> розделе Finally ..перекрыть
Эта фраза выше моего понимания.
← →
balepa © (2006-05-10 14:47) [13]Удалено модератором
← →
KyRo (2006-05-10 15:18) [14]Не 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;
Я просто не вижу где где происходит эта ошибка и мне интересно поможет ли это ?
← →
Сергей М. © (2006-05-10 15:30) [15]
> KyRo (10.05.06 15:18) [14]
>
> Не Finally перекрыть а в TServerClientThread метод Execute
> потому что эта ошибка возникает как раз после выполнения
> метода
> ClientxEcute который и вызывается из метода Execute
>
>
> procedure TServerClientThread.Execute;
> begin
> FServerSocket.ThreadStart(Self);
Галиматьища несусветная ..
← →
KyRo (2006-05-10 15:33) [16]Хорошо из за чего она тогда может быть ?
← →
Сергей М. © (2006-05-10 15:38) [17]Удалено модератором
← →
KyRo (2006-05-10 15:49) [18]Удалено модератором
← →
Сергей М. © (2006-05-10 16:24) [19]
> Ты покажи где кто мне что привел
Галиматья.
Изволь ответить на предыдущую галиматью
> Не Finally перекрыть а в TServerClientThread метод Execute
> > потому что эта
← →
KyRo (2006-05-10 16:29) [20]Удалено модератором
Примечание: Нападки, грубость
← →
Шпиён (2006-05-10 19:30) [21]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;
← →
Пусик © (2006-05-10 19:38) [22]
> 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:45) [23]
> Сергей М. © (10.05.06 14:15) [10]
>
> > тут я его принимаю и присваиваю глобальной переменной
> значение
> > 1
>
>
> Ты здоров, братец ?
>
> Ты только что записал в переменную s что-то там переданное
> рередатчиком сообщения..
А переменная s в данном конкретном случае к AV никакого отношения не имеет.
← →
Пусик © (2006-05-10 19:45) [24]Удалено модератором
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.05.28;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.012 c