Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

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

Posted on 2004-08-30
6
Medium Priority
?
256 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-
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11939672
0
 

Author Comment

by:werehamster-
ID: 11940609
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 700 total points
ID: 11940850
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:werehamster-
ID: 11949200
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 1300 total points
ID: 12041376
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-
ID: 12044079
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
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…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Suggested Courses

609 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