Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.05.28;
Скачать: CL | DM;

Вниз

От чего возникает ошибка   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.042 c
4-1141514317
Piter
2006-03-05 02:18
2006.05.28
Как добавить иконку во всплывающее меню?


3-1142866117
Wolferio
2006-03-20 17:48
2006.05.28
Кодировка DBF файлов


3-1143802532
pmy482
2006-03-31 14:55
2006.05.28
QReport - не забывает старые данные, дублирует


9-1130771485
Finsternis
2005-10-31 18:11
2006.05.28
Прошу помощи у специалистов


11-1126546794
Stargazer
2005-09-12 21:39
2006.05.28
TOnMessage в новом KOL