Entwickler-Ecke

Internet / Netzwerk - Datenmüll bei TServerSocket


PeterPan - Fr 12.08.05 12:28
Titel: Datenmüll bei TServerSocket
hallo leute,

ich habe mal wieder was .... :roll:

mein server soll daten über tcp vom einem client empfangen.

ich habe mir testclients geschrieben die mir daten schicken,
es sind immer streams, die aus einer unbestimmten anzahl von integer werten und einer xml datei bestehen.

integer können aus internet/net byteorder oder host byteorder bestehen, ist erst mal egeal.

der server basiert auf "TServerSocket".

wenn ich nun daten mit "idTcpClient" schicke, funktioniert alles!

code


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:
var
  _Stream: TMemoryStream;
  sLen, tLen : integer;
  IntValue: integer;
  ntLen: LongWord;
begin

  _Stream:= TMemoryStream.Create;
  _Stream.Position:= 0;
  
  sLen:= length(Memo1.Lines.Text);
  tLen:= sLen+36;
  _Stream.Size:= tLen;
  
  // ByteOrder
  // ntLen:= htonl(tLen);
  _Stream.WriteBuffer(tLen, 4);

  IntValue:= StrToInt(ePacketType.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eGsmSen.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eGsmEmpf.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eMsgType.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eTimeOut.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(ePrio.Text);
  _Stream.WriteBuffer(IntValue, 4);

  IntValue:= StrToInt(eRetryC.Text);
  _Stream.WriteBuffer(IntValue, 4);

  _Stream.WriteBuffer(sLen, 4);

  Memo1.Lines.SaveToStream(_Stream);

  TcpClient.OpenWriteBuffer;

  TcpClient.WriteStream(_Stream);

  TcpClient.CloseWriteBuffer;

  _Stream.Free;

end;



wenn ich nun mit TClientSocket daten schicke, komm nur müll an

code


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:
var
  _WinSocketStream: TWinSocketStream;
  _Stream: TMemoryStream;
  sLen, tLen : integer;
  IntValue: integer;
  ntLen: LongWord;
begin

  _Stream:= TMemoryStream.Create;
  _Stream.Position:= 0;


  sLen:= length(Memo1.Lines.Text);
  tLen:= sLen+36;
  _Stream.Size:= tLen;

  //ntLen:= htonl(tLen);
  _Stream.WriteBuffer(tLen, 4);

  IntValue:= StrToInt(ePacketType.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eGsmSen.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eGsmEmpf.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eMsgType.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eTimeOut.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(ePrio.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eRetryC.Text);
  _Stream.WriteBuffer(IntValue, 4);

  _Stream.WriteBuffer(sLen, 4);

  Memo1.Lines.SaveToStream(_Stream);

  _WinSocketStream:= TWinSocketStream.Create(SockClient.Socket, 200);
  _WinSocketStream.Write(_Stream, tLen);
  _WinSocketStream.Free;
  _Stream.Free;
end;


:?:

erster wert "tLen" ist 49 (hbo)
bei idTcpClient = 49
bei TServerSocket = 9358808


lasst mich nicht dumm sterben.

hat jeman ne idee

thx
pp


Narses - Fr 12.08.05 15:02

Moin!

Was auch immer du da tust, du solltest ein Protokoll verwenden. :mahn: :wink:

Warum nimmst du nicht .SendStream?


Delphi-Quelltext
1:
ClientSocket1.Socket.SendStream(_Stream);                    


cu
Narses


PeterPan - Fr 12.08.05 17:30

hallo,

das mir "ClientSocket1.Socket.SendStream(_Stream);" hab ich versucht,
gibt ne fehlermeldung.


Protokoll is leider nicht.diese clients dienen zum testen,
später habe ich keinen einfluss auf dem client.

bitte schau hier mal

Suche in: Delphi-Forum, Delphi-Library DATEN ZWISCHEN RECHNER AUSTAUSCHEN

thx
pp


Narses - Fr 12.08.05 18:12

Moin!

user profile iconPeterPan hat folgendes geschrieben:
das mir "ClientSocket1.Socket.SendStream(_Stream);" hab ich versucht,
gibt ne fehlermeldung.

Prima, komm mir ja nicht auf die Idee auch noch zu verraten, welche das ist. Man könnte ja eventuell was damit anfangen... :wink:

cu
Narses


PeterPan - Di 16.08.05 11:14

hallo,

hier noch ein wenig code


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:
procedure TfrmMainForm.btSockSendClick(Sender: TObject);
var
  //_WinSocketStream: TWinSocketStream;
  _Stream: TMemoryStream;
  sLen, tLen : integer;
  IntValue: integer;
  ntLen: LongWord;
begin

  _Stream:= TMemoryStream.Create;
  _Stream.Position:= 0;


  sLen:= length(Memo1.Lines.Text);
  tLen:= sLen+36;
  _Stream.Size:= tLen;

  //ntLen:= htonl(tLen);
  _Stream.WriteBuffer(tLen, 4);

  IntValue:= StrToInt(ePacketType.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eGsmSen.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eGsmEmpf.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eMsgType.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eTimeOut.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(ePrio.Text);
  _Stream.WriteBuffer(IntValue, 4);
  IntValue:= StrToInt(eRetryC.Text);
  _Stream.WriteBuffer(IntValue, 4);

  _Stream.WriteBuffer(sLen, 4);

  Memo1.Lines.SaveToStream(_Stream);

  //_WinSocketStream:= TWinSocketStream.Create(SockClient.Socket, 200);
  //_WinSocketStream.Write(_Stream, tLen);

  _Stream.Position:= 0;
  SockClient.Socket.SendStream(_Stream);

  //_WinSocketStream.Free;

  _Stream.Free;
end;


bei zeile 44!

der fehler ist eine "EAccessViolation" , wennn das weiter hilft ?

die fehlermeldung ergibt für mich keinen sinn.

thx
pp


PeterPan - Di 16.08.05 11:24

hallo,

habs raus gefunden.


Delphi-Quelltext
1:
ClientSocket1.Socket.SendStream(_Stream);                    


der befehl "SendStream" gibt den Parameter selbst frei

also


Delphi-Quelltext
1:
_Stream.Free;                    


für zu einem fehler.

thx
pp


Narses - Di 16.08.05 11:30

Moin!

user profile iconPeterPan hat folgendes geschrieben:
der befehl "SendStream" gibt den Parameter selbst frei

Nein, tut er nicht. :wink: Der Sendet nur noch, wenn du schon freigeben willst...

Nimm das hier, das gibt den Stream sicher NACH dem Senden frei:

Delphi-Quelltext
1:
ClientSocket1.Socket.SendStreamThenDrop(_Stream);                    


cu
Narses


PeterPan - Di 16.08.05 12:06

hallo,

ok, aber warum gibt es dann das "AccessViolation" ?

und in der hilfe steht das so.

Zitat:

Note: The Stream passed as a parameter to SendStream becomes “owned” by the windows socket object. The Windows socket object frees the stream when it is finished with it. Do not attempt to free the stream after it has been passed as a parameter.


der Befehl

Delphi-Quelltext
1:
ClientSocket1.Socket.SendStreamThenDrop(_Stream);                    



aus der hilfe!

Zitat:

Writes all the information that can be read from the AStream parameter to the socket connection and then terminates the connection.


trennt doch die verbindung? oder?

müsste es halt genau wissen.

thx
pp


Narses - Di 16.08.05 12:09

Moin!

Oh, stimmt :oops: verwechselt, du hast recht. :wink:

cu
Narses


PeterPan - Di 16.08.05 12:35

hallo,

aber danke!

gruss
pp