Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1147329642
zorik
2006-05-11 10:40
2006.05.28
Как выделить в Екселе лист по его названию?


2-1146837440
Dr. Genius
2006-05-05 17:57
2006.05.28
Поиск строк в Pas-модуле Delphi


15-1146261312
lookin
2006-04-29 01:55
2006.05.28
Skype никто не желает?


15-1146751962
oldman
2006-05-04 18:12
2006.05.28
Мама, я очень болен...


2-1147368301
Vitalik__
2006-05-11 21:25
2006.05.28
string





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский