Entwickler-Ecke

Internet / Netzwerk - UDP Client / Fehler 10040 Nachricht zu lang.


jeng - Di 07.07.15 20:30
Titel: UDP Client / Fehler 10040 Nachricht zu lang.
Hallo Community,

Da ist man gerade schön am schreiben und schwups ist das nächste problemchen da.
Vieleicht kann mir hier jemand weiter helfen.

Ich habe 2 funktionen, Exiscan und Exoscan.
Exiscan funktionniert Exoscan nicht.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
Function ExiScan(exiport: integer): integer;

 var
    ExiSBuf: TIdBytes;
    ExiRBuffer: TIdBytes;
    ExiRet: Integer;
    Exi: TidBytes;
    y,i: Integer;

Begin
   


     SetLength(ExiSBuf, 6);
     FillBytes(ExiSBuf, 60);
     SetLength(ExiRBuffer, 11);
     FillBytes(ExiRBuffer, 110);
     SetLength(Exi, 9);
     FillBytes(Exi, 90);

          y:=0;
     For i := exiport to 27 do
        Begin
             y:=y+1;
           ExiSBuf[0] := $23;
           ExiSBuf[1] := HexToByte(IntToHex(i,1));
           ExiSBuf[2] := $0b;
           ExiSBuf[3] := $02;
           ExiSBuf[4] := $49;
           ExiSBuf[5] := $49;
             // 23 0b 15 07 05 00 15 02  02 00 10 answer Exi 2 present
            Exi[0] := $23;
            Exi[1] := $0B;
            Exi[2] := HexToByte(IntToHex(i,1));
            Exi[3] := $07;
            Exi[4] := $05;
            Exi[5] := $00;
            Exi[6] := HexToByte(IntToHex(i,1));
            Exi[7] := $02;
            Exi[8] := HexToByte(IntToStr(y));

            Form4.IdUDPClient1.Sendbuffer(IP, strtoint(Form4.Edit2.Text), ExiSBuf);

            Sleep(25);
            ExiRet := Form4.IdUDPClient1.ReceiveBuffer(ExiRBuffer,Sizeof(ExiRBuffer));

            if ExiRet  > 0 then
                   begin
                      SetLength(ExiRBuffer, ExiRet -2);
                      if  not ByteArrayPos(Exi, ExiRBuffer) = 0 then
                     // Form4.Memo1.lines.add('Nothing detected')
                     else
                   //Form4.Memo1.lines.add(IntToStr(ByteArrayPos(RBuffer, Exi)));
                   Form4.Memo1.lines.add('Exi '+IntToStr(Exi[8])+' at adr: '+IntToStr(Exi[2]));
                    Result := Exi[8];
          //        Memo1.lines.add('Bla');
          //       use RBuffer as needed...
                   end;

            end;

 end;


Also diese listet mir die Exi´s auf.
Nächste soll genau das gleiche tun, tut sie aber nicht.
Sondern springt immer mit dem Fehler 10040 Nachricht zu lang raus.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
Function ExoScan(exoport: integer): integer;
 var
    ExoSBuf: TidBytes;
    ExoRBuffer: TIdBytes;
    ExoRet: Integer;
    Exo: TidBytes;
    y,a: Integer;

 Begin

     SetLength(ExoSBuf, 6);
     FillBytes(ExoSBuf, 60);
     SetLength(ExoRBuffer, 11);
     FillBytes(ExoRBuffer, 110);
     SetLength(Exo, 9);
     FillBytes(Exo, 90);

          y:=0;
    For a := exoport to 75 do
           Begin
            y:=y+1;
            ExoSBuf[0] := $23;
            ExoSBuf[1] := HexToByte(IntToHex(a,1));
            ExoSBuf[2] := $0b;

            ExoSBuf[3] := $02;
            ExoSBuf[4] := $49;
            ExoSBuf[5] := $49;
            // Exo1 23 0b 3c 07 05 00 3c 03  01 00 3b
            Exo[0] := $23;
            Exo[1] := $0B;
            Exo[2] := HexToByte(IntToHex(a,1));
            Exo[3] := $07;
            Exo[4] := $05;
            Exo[5] := $00;
            Exo[6] := HexToByte(IntToHex(a,1));
            Exo[7] := $03;
            Exo[8] := HexToByte(IntToStr(y));

              Form4.IdUDPClient1.Sendbuffer(IP, strtoint(Form4.Edit2.Text), ExoSBuf);
              Sleep(25);
              ExoRet := Form4.IdUDPClient1.ReceiveBuffer(ExoRBuffer,Sizeof(ExoRBuffer));

             if ExoRet  > 0 then
                   begin
                      SetLength(ExoRBuffer, ExoRet -2);   //ExoRet -2
                      if  not ByteArrayPos(Exo, ExoRBuffer) = 0 then
                        //Form4.Memo1.lines.add('Nothing detected')
                       else
                        // Form4.Memo1.lines.add(IntToStr(ByteArrayPos(ExoRBuffer, Exo)));
                        Form4.Memo1.lines.add('Exo '+IntToStr(Exo[8])+' at adr: '+IntToStr(Exo[2]));
                        Result := Exo[8];
                    end;
          //        Memo1.lines.add('Bla');

          //       use RBuffer as needed...
            end;
 end;


Vieleicht liegt es ja an dieser function (hab die auf Stack Overflow gefunden)
Sie tut ansich genau das was ich brauche.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function ByteArrayPos(const SearchArr : array of byte; const CompArr : array of byte) : integer;
//  result=Position or -1 if not found
var
  Comp,Search : AnsiString;
begin
  SetString(Comp, PAnsiChar(@CompArr[0]), Length(CompArr));
  SetString(Search, PAnsiChar(@SearchArr[0]), Length(SearchArr));
  Result := Pos(Search,Comp) - 1;
end;


Und so wird das ganze aufgerufen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm4.Button2Click(Sender: TObject);

 var
    c,x: Integer;

    begin
        //Memo1.Lines.Add('Scanning Exis...'); //IntToStr(ExiScan(x)));
        For x := 20 to 27 do
           begin
             ExiScan(x);
           // Memo1.Lines.Add(IntToStr(ExiScan(x)));
           end;

         Sleep(50);

       Memo1.Lines.Add('Scanning Exos...');
        For c := 60 to 75 do        //75
           begin
             ExoScan(c);
           end;

    end;


JoelH - Mi 08.07.15 10:28

Vielleicht stehe ich ja auf dem Schlauch, aber was soll diese Zeile bewirken?

Delphi-Quelltext
1:
ExoRet := Form4.IdUDPClient1.ReceiveBuffer(ExoRBuffer,Sizeof(ExoRBuffer));                    


Die Beschreibung meines Delphis gibt folgendes zur Methode her:

TIdUDPClient.ReceiveBuffer Method (TIdBytes, Integer);

Parameters Description
var ABuffer: TIdBytes Buffer where received data is stored.
const AMSec: Integer = IdTimeoutDefault Milliseconds to wait for a readable connection.


Warum setzt den Timeout auf Sizeof(ExoRBuffer)? Hast du dich da vielleicht vertan, denn "gefühlt" hätte ich jetzt gesagt dein Plan war es die Länge von ExoRBuffer auf die Länge der empfangenen Bytes zu setzen. Wwas du aber nicht tust, denn du setzt anstatt dessen einfach den Timeout . Naja und weiter unten verkürzt du das Array immer weiter. Und m.E. ist das Array dann einfach zu kurz um die Receivingdata auf zu nehmen.


jeng - Mi 08.07.15 12:35

user profile iconJoelH hat folgendes geschrieben Zum zitierten Posting springen:
Vielleicht stehe ich ja auf dem Schlauch, aber was soll diese Zeile bewirken?

Delphi-Quelltext
1:
ExoRet := Form4.IdUDPClient1.ReceiveBuffer(ExoRBuffer,Sizeof(ExoRBuffer));                    


Die Beschreibung meines Delphis gibt folgendes zur Methode her:

TIdUDPClient.ReceiveBuffer Method (TIdBytes, Integer);

Parameters Description
var ABuffer: TIdBytes Buffer where received data is stored.
const AMSec: Integer = IdTimeoutDefault Milliseconds to wait for a readable connection.



Ja da hast du recht, mein fehler! Ich wollte wie vermutet die länge ermitteln.
Was währe denn die normale dauer für den Timeout? Hab den jetzt mal auf 50ms gesetzt.

Zitat:

Warum setzt den Timeout auf Sizeof(ExoRBuffer)? Hast du dich da vielleicht vertan, denn "gefühlt" hätte ich jetzt gesagt dein Plan war es die Länge von ExoRBuffer auf die Länge der empfangenen Bytes zu setzen. Wwas du aber nicht tust, denn du setzt anstatt dessen einfach den Timeout . Naja und weiter unten verkürzt du das Array immer weiter. Und m.E. ist das Array dann einfach zu kurz um die Receivingdata auf zu nehmen.


Der ExoRBuffer hat immer eine länge von 11 bytes, die ich dann auf die länge von Exo also 9 bytes bringe um diese zu vergleichen. Die letzten 2 bytes von ExoRBuffer interessieren mich nicht!
Deshalb

Delphi-Quelltext
1:
2:
                      SetLength(ExoRBuffer, ExoRet -2);   //ExoRet ist immer 11 bytes also -2 um auf länge Exo 9 bytes zu bringen.
                      if  not ByteArrayPos(Exo, ExoRBuffer) = 0 then