473,807 Members | 2,851 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Buffering TCPIP data

I have a TCPIP socket providing data to my app.
My app works on messages (not textual) with a predefined footer (eg 0x01
followed by 0x02)

How should i go about buffering this and retrieving the complete messages ?

Current approach:
I have a byte array of eg 1MB to hold data until full messages are assembled
when socket is readable, i read all data into the buffer starting at the pos
after the last byte of data that was put into it (maintained through an
integer var LastPos).
A separate thread would scan the array when new data is added. If it finds
the footer 0x01,0x02 then it will take all data before this and copy it out
into a new array and publish this through an event argument as a
MessageRecieved event.
IMPORTANTLY it will then take all data after the 0x02 char and move it to
the front of the buffer.

Is this the best approach ?
Should i be using a Queue of type byte ?
Thoughts much appreciated

Thanks.
S.

Jun 27 '08 #1
9 1786
On Jun 6, 3:06 pm, ShaunO <Sha...@discuss ions.microsoft. comwrote:
I have a TCPIP socket providing data to my app.
My app works on messages (not textual) with a predefined footer (eg 0x01
followed by 0x02)

How should i go about buffering this and retrieving the complete messages ?

Current approach:
I have a byte array of eg 1MB to hold data until full messages are assembled
when socket is readable, i read all data into the buffer starting at the pos
after the last byte of data that was put into it (maintained through an
integer var LastPos).
A separate thread would scan the array when new data is added. If it finds
the footer 0x01,0x02 then it will take all data before this and copy it out
into a new array and publish this through an event argument as a
MessageRecieved event.
IMPORTANTLY it will then take all data after the 0x02 char and move it to
the front of the buffer.

Is this the best approach ?
Should i be using a Queue of type byte ?
Thoughts much appreciated
It sounds like you really want to create a circular buffer - although
then you *do* need to know the maximum size you'll ever run into, or
cope with the complexity of recreating the buffer as and when you need
to.

Your current solution sounds okay though. A Queue<bytewould work,
but extracting a whole range out as an array may be painful (I haven't
checked the API). It'll still have to do copying, anyway.

Jon
Jun 27 '08 #2
t'was my fault for mentioning Queue<T(in the lack the full context);
although reasonable for many producer/consumer scenarios, in this case
probably not ;-p

Marc
Jun 27 '08 #3
The messages could be any size but never likely to go above 128 bytes.
It would be very helpful if you could outline the benefits of a circular
buffer over the byte array that i outlined so that i can evaluate if i need
to re-implement.
Thanks,
Shhaun
"Jon Skeet [C# MVP]" wrote:
On Jun 6, 3:06 pm, ShaunO <Sha...@discuss ions.microsoft. comwrote:
I have a TCPIP socket providing data to my app.
My app works on messages (not textual) with a predefined footer (eg 0x01
followed by 0x02)

How should i go about buffering this and retrieving the complete messages ?

Current approach:
I have a byte array of eg 1MB to hold data until full messages are assembled
when socket is readable, i read all data into the buffer starting at the pos
after the last byte of data that was put into it (maintained through an
integer var LastPos).
A separate thread would scan the array when new data is added. If it finds
the footer 0x01,0x02 then it will take all data before this and copy it out
into a new array and publish this through an event argument as a
MessageRecieved event.
IMPORTANTLY it will then take all data after the 0x02 char and move it to
the front of the buffer.

Is this the best approach ?
Should i be using a Queue of type byte ?
Thoughts much appreciated

It sounds like you really want to create a circular buffer - although
then you *do* need to know the maximum size you'll ever run into, or
cope with the complexity of recreating the buffer as and when you need
to.

Your current solution sounds okay though. A Queue<bytewould work,
but extracting a whole range out as an array may be painful (I haven't
checked the API). It'll still have to do copying, anyway.

Jon
Jun 27 '08 #4
On Jun 6, 3:41 pm, ShaunO <Sha...@discuss ions.microsoft. comwrote:
The messages could be any size but never likely to go above 128 bytes.
It would be very helpful if you could outline the benefits of a circular
buffer over the byte array that i outlined so that i can evaluate if i need
to re-implement.
You'd implement the circular buffer with an underlying byte array - it
means that when you've copied the data out for the message, you can
just update the logical "next message start" to the end of the
previous one, with no extra copying involved - i.e. you don't copy the
data you've already received from the next message.

Jon
Jun 27 '08 #5
Just an idea - If you know that your message always ends in 0x01,0x02 why
not build each message on the fly?

Allocate a new block.
When you get something in from the socket, copy it byte by byte into the
block, checking for the footer.
When you find your footer :
1) Fire an event with the now-complete message
2) Allocate a new block and start copying into that.

I guess copying byte by byte when you get the TCP data in seems tedious -
but you have to check the data anyway so you know when your message is
finished.

Personally, I wouldn't go for a separate thread scanning the same buffer my
TCP socket was writing into.
If you use an event I don't think you need to worry about thread synching at
all since the message in the event is in a block your TCP thread has
finished with.

Just don't take too long in the event handler - now here's somewhere where
you might use a synchronized queue. So your handler just pushes the block on
the queue and then returns to your TCP code to finish handling the TCP
event.

Another worker thread can be looking at your queue and pulling messages off
and handling them while your TCP code isn't doing anything.

HTH,

Adam.
=========

"ShaunO" <Sh****@discuss ions.microsoft. comwrote in message
news:CE******** *************** ***********@mic rosoft.com...
>I have a TCPIP socket providing data to my app.
My app works on messages (not textual) with a predefined footer (eg 0x01
followed by 0x02)

How should i go about buffering this and retrieving the complete messages
?

Current approach:
I have a byte array of eg 1MB to hold data until full messages are
assembled
when socket is readable, i read all data into the buffer starting at the
pos
after the last byte of data that was put into it (maintained through an
integer var LastPos).
A separate thread would scan the array when new data is added. If it finds
the footer 0x01,0x02 then it will take all data before this and copy it
out
into a new array and publish this through an event argument as a
MessageRecieved event.
IMPORTANTLY it will then take all data after the 0x02 char and move it to
the front of the buffer.

Is this the best approach ?
Should i be using a Queue of type byte ?
Thoughts much appreciated

Thanks.
S.

Jun 27 '08 #6
(final question)
How does this handle the wrapping around - is there native support for doing
this somehow or would i need to check the pos left in buffer and break into
two parts putting one bit a the end of the buffer and the remainder at the
start ?
Thanks,
Shaun

"Jon Skeet [C# MVP]" wrote:
On Jun 6, 3:41 pm, ShaunO <Sha...@discuss ions.microsoft. comwrote:
The messages could be any size but never likely to go above 128 bytes.
It would be very helpful if you could outline the benefits of a circular
buffer over the byte array that i outlined so that i can evaluate if i need
to re-implement.

You'd implement the circular buffer with an underlying byte array - it
means that when you've copied the data out for the message, you can
just update the logical "next message start" to the end of the
previous one, with no extra copying involved - i.e. you don't copy the
data you've already received from the next message.

Jon
Jun 27 '08 #7
On Jun 6, 4:45 pm, ShaunO <Sha...@discuss ions.microsoft. comwrote:
(final question)
How does this handle the wrapping around - is there native support for doing
this somehow or would i need to check the pos left in buffer and break into
two parts putting one bit a the end of the buffer and the remainder at the
start ?
The latter - that's exactly why it would be a case of writing a
circular buffer instead of using an existing one :)

(There may well be existing third party implementations around already
- but your case is somewhat specialised as you'll want good support
for dealing with whole arrays of bytes rather than one byte at a
time.)

Jon
Jun 27 '08 #8
On Fri, 06 Jun 2008 08:45:01 -0700, ShaunO
<Sh****@discuss ions.microsoft. comwrote:
(final question)
How does this handle the wrapping around - is there native support for
doing
this somehow or would i need to check the pos left in buffer and break
into
two parts putting one bit a the end of the buffer and the remainder at
the
start ?
There is no built-in support for a circular buffer, AFAIK. You'd have to
implement the wrap-around logic yourself. Not _too_ hard, but can be a
little tricky.

That said, if you really need high-performance, it's probably the way to
go. Shifting all your data is potentially expensive, especially for a 1MB
buffer (alternatively, if your individual messages are relatively small,
are you sure you really need such a large buffer?).

Of course, if you don't need high-performance, you may want to consider
using much simpler techniques. For example, use smaller buffers for the
individual network i/o operations (anywhere from 1K up to 8K or so
depending on your usage), and then write the results into a MemoryStream
that represents each individual message. When you reach the terminator,
handle the current message by converting to bytes
(MemoryStream.T oArray()), passing to whatever code will actually process
it, and then start a new MemoryStream with the remaining bytes in your i/o
buffer.

That approach is likely to be much simpler than a circular buffer or
similar technique. If the performance is sufficient for your needs, IMHO
it's a much better way to go.

Pete
Jun 27 '08 #9
Thanks!

"Peter Duniho" wrote:
On Fri, 06 Jun 2008 08:45:01 -0700, ShaunO
<Sh****@discuss ions.microsoft. comwrote:
(final question)
How does this handle the wrapping around - is there native support for
doing
this somehow or would i need to check the pos left in buffer and break
into
two parts putting one bit a the end of the buffer and the remainder at
the
start ?

There is no built-in support for a circular buffer, AFAIK. You'd have to
implement the wrap-around logic yourself. Not _too_ hard, but can be a
little tricky.

That said, if you really need high-performance, it's probably the way to
go. Shifting all your data is potentially expensive, especially for a 1MB
buffer (alternatively, if your individual messages are relatively small,
are you sure you really need such a large buffer?).

Of course, if you don't need high-performance, you may want to consider
using much simpler techniques. For example, use smaller buffers for the
individual network i/o operations (anywhere from 1K up to 8K or so
depending on your usage), and then write the results into a MemoryStream
that represents each individual message. When you reach the terminator,
handle the current message by converting to bytes
(MemoryStream.T oArray()), passing to whatever code will actually process
it, and then start a new MemoryStream with the remaining bytes in your i/o
buffer.

That approach is likely to be much simpler than a circular buffer or
similar technique. If the performance is sufficient for your needs, IMHO
it's a much better way to go.

Pete
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
15948
by: MPowell | last post by:
Gents/Ladies, I'm doing (at least plan on ) lots of Reads and Writes across a communication channel. I'm told that for the 'receive side' it'd be prudent to implement a double buffering scheme to handle all the asnychronous inputs. Someone mentioned Herb Shutters book as frame of reference, nonetheless, could someone provide sample code or - in effect an outline of double buffering? I've perused the web but most references are to...
0
2357
by: Stuart Norris | last post by:
Dear Group, I am having a problem setting SocketOptionName.SendTimeout on a client TCPIP application using the sockets in .NET. From the on-line help it is possible to set a SocketOptionName.SendTimeout for sends on TCPIP sockets. In all the tests that I have done with both Async and Sync sends the send returns immediately with the number of bytes sent (< 100 in my messages).
3
4202
by: TulasiKumar | last post by:
hi all, My requirment is i want to listen one perticular TCPIP port for one IPAddress,Wheneverver the data in coming to this port that data i will be save one text file..For example:www.msdn.microsoft.com is fixed with some TCPIP port.Whene ever data is coming in to the TCPIP that data i will be saved one text file.I have done the code regrading my requirement.Whenever i have started my listner class it was giving one exception ,the...
1
3215
by: coolsti | last post by:
I am having a curious problem with Vista working on a Lenovo thinkpad. To test and demonstrate this problem, I have a PHP script that does not terminate. It enters an infinite loop where it repeatedly prints out a line of data, flushes output buffers (with appropriate PHP functions), then sleeps for a number of seconds. In other words, this represents a constant input stream to the browser which is requesting the script as a page. On my...
0
9719
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10371
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10374
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10111
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9193
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7650
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6877
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
2
3853
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3010
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.