Avatar billede mora Nybegynder
30. maj 2001 - 13:15 Der er 25 kommentarer og
2 løsninger

Array / lister error

Jeg får en fejl så snart denne timer udføres.
(Access Violation)
Eneste undtagelse er hvis  lstUsers.Items.Count=0



procedure TfrmServidor.Timer1Timer(Sender: TObject);
var
retorno : TMsg;
i : integer;
begin
{
  for i:=0 to length(A) do
Memo1.Lines.add(\'A\'+A[i]+\'B\'+B[i]);
}




if lstUsers.Items.Count>0 then
begin
  SetLength(A, lstUsers.Items.Count);
  SetLength(B, lstUsers.Items.Count);

          for i:=0 to lstUsers.Items.Count-1 do
          //Array A contains usernames
          //Array B contains a integer for ping result (0 until answered)
        begin
            memo1.Lines.Add(\'Pinging user \'+lstUsers.Items.Strings[i]);

            retorno.Tipo := MSG_PING;
            retorno.destinatario := lstUsers.Items.Strings[i];
            sscChat.Socket.Connections[i].SendBuf( retorno, SizeOf(TMsg) );
        A[i]:=lstUsers.Items.Strings[i];
        B[i]:=0;
        end;
end;
end;
Avatar billede martinlind Nybegynder
30. maj 2001 - 13:28 #1
er det ikke fordi du glemmer at A er 0..end så du skal skrive length(a)-1 i din for løkke

/Martin
Avatar billede sjensen Nybegynder
30. maj 2001 - 13:31 #2
ret denne linie

retorno.destinatario := lstUsers.Items.Strings[i];

til

retorno.destinatario := lstUsers.Items[i];

og tilsvarende med

A[i]:=lstUsers.Items.Strings[i];

til

A[i]:=lstUsers.Items[i];


Avatar billede sjensen Nybegynder
30. maj 2001 - 13:32 #3
martinlind, forløkken er i mellem tuborgparanteser og derfor ikke med i programmet
Avatar billede martinlind Nybegynder
30. maj 2001 - 13:36 #4
sjensen >> ja det er rigtigt jeg så det som timer proceduren og resten som main prog.

Men jeg vil nu godt havde lov at tvivle på din løsning, hvad skulle forskellen være på at benytte sig at default property\'en og ikke ??
Avatar billede mora Nybegynder
30. maj 2001 - 13:44 #5
Det hjalp ikke ...

if lstUsers.Items.Count>0 then
begin
  SetLength(A, lstUsers.Items.Count);
  SetLength(B, lstUsers.Items.Count);

          for i:=0 to lstUsers.Items.Count-1 do
        begin
            memo1.Lines.Add(\'Pinging user \'+lstUsers.Items.Strings[i]);

            retorno.Tipo := MSG_PING;
            retorno.destinatario := lstUsers.Items[i];
            sscChat.Socket.Connections[i].SendBuf( retorno, SizeOf(TMsg) );
        A[i]:=lstUsers.Items[i];
        B[i]:=0;
        end;
end;
Avatar billede martinlind Nybegynder
30. maj 2001 - 13:52 #6
Nej Selvfølgelig ikke !, fejlen er at du et eller andet sted i din løkke for index\'eret du ud over enten en af dinne array\'s eller i din liste.

Du må slå debug til og se hvor delphi breaker, det kan vel også meget vel være dinne connections du index\'er ud over.

/Martin
Avatar billede mora Nybegynder
30. maj 2001 - 13:58 #7
Hvilken debug, skal jeg indsætte en break point, eller hvad ?

Jeg plejer at arbejde i Delphi3, så kender ikke alle de nye funktioner i Delphi5 :)
Avatar billede sjensen Nybegynder
30. maj 2001 - 14:05 #8
Martinlind, det har du selvfølgeligt ret i. Det er kun fordi det er unødvendigt. Items[x] er tilstrækkeligt.

Men jeg tror nu Mora har problemet i denne linie:

sscChat.Socket.Connections[i].SendBuf( retorno, SizeOf(TMsg) );

Det bør vel være sizeof(retorno) eftersom tmsg er en klasse og ikke en variabel
Avatar billede martinlind Nybegynder
30. maj 2001 - 14:05 #9
Ja, prøv at sætte et break point, og kør rundt i din løkke så tror jeg du finder det, du kan også vælge om delphi skal stoppe på en exception eller om den skal \"bruge\" dine try except løkker, det er \"tools/debugger options\" du skal ind i, men jeg på tilstå jeg tror den kommer ved Connections[i], du kan evt. prøve at skrive sådan

if sscChat.Socket.ConnectionCount > i then
sscChat.Socket.Connections[i].SendBuf( retorno, SizeOf(TMsg) );
       

jeg ved ikke om det lige er connectionscount den hedder, men check på om i er støre end antal conn.

/Martin
Avatar billede martinlind Nybegynder
30. maj 2001 - 14:08 #10
sjensen >> Måske men på den anden side en sizeof på en classe retunere jo bare sizen på en pointer, så skulle det ikke bare betyde at der ikke kommer alt med over, men det er helt sikker den line der er problemmet på den ene eller anden måde.

/Martin
Avatar billede mora Nybegynder
30. maj 2001 - 14:17 #11
Det er den linje :(

sscChat.Socket.Connections[i].SendBuf( retorno, SizeOf(retorno) );

Hvis jeg smider den i { }  virker det nemlig ...


Avatar billede mora Nybegynder
30. maj 2001 - 14:18 #12
Men denne linje kommer rigtigt nok ?
            memo1.Lines.Add(\'Pinging user \'+lstUsers.Items.Strings[i]);

Den finder brugeren ...
Avatar billede sjensen Nybegynder
30. maj 2001 - 14:23 #13
en anden ting er din brug af i-et som index. Det bruger du også til socket.connections[i]

Eru du sikker på at du har lige så mange
connections som du har items i listen ?

Og, men timere af denne art er det en god ide at disable timeren i starten og så re-aktivere den igen ved afslutningen. Derved undgår du en overlapning hvis udførelsen af timeren tager længere tid end tiden inden timeren aktiveres igen.

d.v.s. i starten af timeren skriver du:

timer1timer.enabled := false;

og før den sidste end skriver du

timer1timer.enabled := true;
Avatar billede martinlind Nybegynder
30. maj 2001 - 14:25 #14
TMsg er en Classe Delphi har defineret, så du skal nøjes med at overføre de data den indeholder og ikke selve classevariablen, det kan du nemlig ikke på den måde, og det er nok som sjensen skrev, sizeof(TMsg) retunere 4 som er størelsen på en pointer, og det var jo ikke kun fire byte du vil overføre. Hvorfor bruger du TMsg ?

/Martin
Avatar billede mora Nybegynder
30. maj 2001 - 14:26 #15
Sjensen: Ja, jeg har lige mange connections som items i listen.


Denne lille funktion når at pinge brugeren, brugeren retuner svar og så får den error ?

procedure TfrmServidor.Button2Click(Sender: TObject);
var
retorno : TMsg;
i : integer;
begin
      for i:=0 to lstUsers.Items.Count-1 do
      begin
            retorno.Tipo := MSG_PING;
            retorno.destinatario := lstUsers.Items[i];
            sscChat.Socket.Connections[i].SendBuf( retorno, SizeOf(TMsg) );
            memo1.Lines.Add(\'Pinging user \'+lstUsers.Items.Strings[i]);
      end;
end;
Avatar billede mora Nybegynder
30. maj 2001 - 14:36 #16
Prøvede at skifte den med activeconnections virkede heller ikke ...
Men programmet kan køre videre, efter 2 fejl ...


      for i:=0 to sscChat.Socket.ActiveConnections-1 do
Avatar billede mora Nybegynder
30. maj 2001 - 14:40 #17
Hvis 2 klienter logger på, og jeg lukker den sidste connection, virker programmet med den sidste ...
Men ikke hvis jeg lukker den første, og lader den anden være åben.

(Lukker funktion)
    if ExistsUser(userkill) >= 0 then
begin
      for i:=0 to lstUsers.Items.Count-1 do
    if trim(userkill) = trim(lstUsers.Items.Strings[i]) then
      v:=i;

      sscChat.Socket.Connections[v].SendBuf( retorno, SizeOf(TMsg) );
            memo1.Lines.Add(\'Killed user \'+userkill);
end
else
memo1.lines.add(\'User not found \'+userkill);
Avatar billede mora Nybegynder
30. maj 2001 - 14:42 #18
Det var ikke hele funktionen ...

procedure TfrmServidor.Button1Click(Sender: TObject);
var
userkill : string;
retorno : TMsg;
v,i : integer;
begin
v:=0;
      userkill := InputBox(\'What user to kill ?\', \'Kill User\', \' \');

    retorno.Tipo := MSG_KILL;
    retorno.destinatario := userkill;

    if ExistsUser(userkill) >= 0 then
begin
      for i:=0 to lstUsers.Items.Count-1 do
    if trim(userkill) = trim(lstUsers.Items.Strings[i]) then
      v:=i;

      sscChat.Socket.Connections[v].SendBuf( retorno, SizeOf(TMsg) );
            memo1.Lines.Add(\'Killed user \'+userkill);
end
else
memo1.lines.add(\'User not found \'+userkill);

      end;
Avatar billede martinlind Nybegynder
30. maj 2001 - 15:14 #19
Hvilken Socket comp bruger du ??
Avatar billede mora Nybegynder
30. maj 2001 - 15:29 #20
Tserversocket
Avatar billede martinlind Nybegynder
30. maj 2001 - 16:21 #21
Hvis det er delphi\'s egen, kan du faktisk også godt havde problemet DER, jeg ved at hvis man skal havde noget der skal gøre ret meget mere en en connection, er men bedst stillet med at lave det selv ( WIN-API ) eller måske prøve med INDY\'s
Det lugter jo kraftigt af at det er Socket.conn der er problemet.

/Martin
Avatar billede mora Nybegynder
30. maj 2001 - 17:45 #22
Det er jo kun den del der ikke virker ?

Brugerne kan sakkens chatte sammen, og jeg kan godt kicke dem fra serveren.
Det jeg vil lave er en funktion der tjekker om alle der er connectet stadig svarer, der er jo sikkert nogle med windows der ikke kører så stabilt :)
Avatar billede sjensen Nybegynder
30. maj 2001 - 17:52 #23
øhm.. det er måske et dumt spørgsmål, men er du sikker på at dine socket connections er åbne ?

Du skal jo sørge for at åbne en connection inden du kan bruge sendbuf. Og jeg har altid en timeout på 2-400 ms fra Open til den første sendbuf. Ellers får jeg også access violation.
Avatar billede mora Nybegynder
30. maj 2001 - 18:21 #24
Det er jeg ret sikker på, jeg kan jo som sagt kicke dem, og sende deres beskeder videre ?

Men hvad er kommandoen ?
Avatar billede martinlind Nybegynder
30. maj 2001 - 20:11 #25
Det var præcis det med \"lost connections\" jeg mener var problemet med TServersoket, så måske skulle du prøve om du kan strikke noget test sammen men en INDY comp. i stedet, det ville jeg gøre i dit sted, og hvis det ikke virker, så er der jo ren win-API, det virker, Winsocket kan godt håndtere \"lost connection\".

Avatar billede mora Nybegynder
30. maj 2001 - 20:42 #26
Nogen der har nogle links til winsocket og/eller indy ?
Avatar billede martinlind Nybegynder
30. maj 2001 - 22:29 #27
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester