Solved

Example Source of Reliable TCP Packets with Headers and Data, OOP.

Posted on 2004-08-30
6
249 Views
Last Modified: 2013-11-23
Greetings,

I need some good example code that deals with TCP packets where there is a known header with data length as part of the header (including header) and data.

Would like it to be asyncronous if possible.  I need to be able to send data from a memo line and stuff.  Perhaps an OnPacket event or something that gets called where there is a full packet available.

Anyway, this is what I am working with.

(BYTE)      StartPacket - always 0xFF
(BYTE)      Packet ID
(WORD)    Packet length, including this header
(VOID)      Packet Data

I did get something sort of working with using Indy Client, but it gets stuck in between packets and I can't send anything.  Also I find it crashes with errors when you close the program while it is waiting for data to read and stuff.

I would love for it to be OOP (object oriented programming).  Meaning making a object that is based off of TObject and has an event of OnPacket or something that is called when it gets a full packets with all the data and stuff and passes the data along to the event.

OnPacket(PacketID, Length, data)


Anyway, here is some source I got so far that I want to scratch and use some asycronious method...  I'd really not like to have to deal with threads is if I don't have to.

      while BNET.Connected do
      begin
        try
          BNET.ReadBuffer(StartPacket,1);
          BNET.ReadBuffer(PacketID,1);
          BNET.ReadBuffer(AByte,1);
          BNET.ReadBuffer(PacketLength,1);
          PacketLength := (PacketLength SHL 8) + AByte;
          BNET.ReadBuffer(PacketData,PacketLength-4);
        except
          on E: Exception do
            begin
              OutPutBox.Lines.Add('Error: '+E.Message);
              BNET.Disconnect
            end;
        end;
        Case StartPacket of
          $FF :
            Case PacketID of
              SID_CLANINVITE : OutPutBox.Lines.Add('  SID_CLANINVITE');
              //...
              SID_CLANMOTD : OutPutBox.Lines.Add('  SID_CLANMOTD');
          Else
            Begin
            End;
        End;
        If Terminated then BNET.Disconnect;
      end;

PS - I'd love to be able to give more than 500 points for this too, but it won't let me.  :)
0
Comment
Question by:werehamster-
6 Comments
 
LVL 12

Expert Comment

by:Ivanov_G
Comment Utility
0
 

Author Comment

by:werehamster-
Comment Utility
Not exactly what I am looking for.  I did, however, figure out how to make a good reader thread that seems to work well.  I'll leave this up for the purpose of others looking into this topic to find an answer.

I do have a side question though, I have an indy client, when I disconnect while in the GUI, I get an error message.  When I run the executable seperately, it runs fine.  Any thoughts?
0
 
LVL 2

Assisted Solution

by:Molando
Molando earned 175 total points
Comment Utility
You are probably getting ConnectionClosedGracefully.
Do not worry about this, this is normal. Just get delphi to ignore these errors when in the GUI.
tools->debugger options->language exceptions->add->EldSilentException
(may have not spelt that correctly, check the indy docs.
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 

Author Comment

by:werehamster-
Comment Utility
Got another stupid, unrelated question.

I am reading a TCP Packet.  Parts are called a DWord in the description, but is not the same as a delphi DWord.

It is only 2 bytes long, but the bytes are reversed I think...

ie:/ 0100 = 0001,  0001 = $0100, etc.

I assume that is not how a word is stored normally when you Writebuffer(aword,sizeof(aword));

There a really quick way to reverse the bytes that I do not know?  Right now, I am reading 1 byte, then adding the 2nd byte with SHL 8.  re: Value = Byte1 + Byte2 SHL 8.  Is there a faster/quicker/better way than what I am doing?

I'll divide the points appropriately for those that can give good advice on this.  If I had a whole string of these, I was thinking that I could do...

Blah = (Blah and $0F0F0F0F) SHL 8 + ((Blah and $F0F0F0F0) SHR 8)

Any thoughts/advice?
0
 
LVL 10

Accepted Solution

by:
Jacco earned 325 total points
Comment Utility
Hi there,

(just nosing around in your questions) ;-)

This might be fast,

function ReverseWord(const aWord: Word): Word;
begin
  Result := Lo(aWord) shl 8 or Hi(aWord);
end;

To see how a word is built up from bytes:

procedure TForm1.Button1Click(Sender: TObject);
var
  lWord: Word;
  lSS: TStringStream;
begin
  lSS := TStringStream.Create('');
  try
    lWord := Ord('A') shl 8 + Ord('B'); // Hi = A Lo = B
    lSS.WriteBuffer(lWord, 2);
    Memo1.Lines.Add(lSS.DataString);
  finally
    lSS.Free;
  end;
end;

It shows "BA" so the low byte is stored first just like in you sample, so I think you don't need to reverse at all.

I think you can do it this:

  var
    PacketLength: Word;
  ...
  while BNET.Connected do
      begin
        try
          BNET.ReadBuffer(StartPacket,1);
          BNET.ReadBuffer(PacketID,1);
          BNET.ReadBuffer(PacketLength,2);
          BNET.ReadBuffer(PacketData,PacketLength-4);

Or of course the buffered reading I showed in my comment in your other question.

Did you have time to test the code?

Regards Jacco
0
 

Author Comment

by:werehamster-
Comment Utility
Didn't have much time to test much of anything yet.  Got a couple days off to do it today and tommorow though.  I'll see if I can fit it into my busy schedule.  Rewriting a huge portion of my code, not just networking.  I'm a stickler for stability.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now