473,406 Members | 2,217 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

TCP application - Synchronization issue??

Hi

I am developing an application in C#. The application creates a
TCPListener object and listens to (incoming) data on a particular
port. A simulator hardware writes data to this port. My application
reads the data and process it and generates some results for display.

The TCPListener object waits for incoming data in a background thread.
The amount of data that is being written is large (around 100 KBytes
in one go). The thread listening for incoming data does not do much
processing. It allocates a buffer of large enough size and waits for
some data to be written on the port (TCPListener.Read() ). Once the
data arrives, it resizes the buffer to the size of the data written
and enqueues it in a Queue object. It then sets an AutoResetEvent to
which other thread is waiting. (That thread then dequeues the data and
processes it).

The hardware is expected to write data in multiple of 4 bytes. If the
number of bytes written to the port is not multiple of 4 then it is
error condition. I am observing that sometimes the application does
not recieve the data of size which is multipe of 4. I am believing
that the hardware is producing correct application data. However,
there is a synchronisation issue for the software application. Before
the previous read is complete, the hardware seems to write new data.
Is this possible? If yes, then how does windows socket mechanism
handle it? Does it buffer the new data internally and then make it
available to the application once the previous read is over? I need
some clarity here. Can anyone explain how the underlying windows
socket mechanism work when there is a simultaneous read/write to an
application port?

Thanks in advance
Best regards
Amit Dedhia

Mar 23 '07 #1
5 1341

"Amit" <am********@yahoo.comwrote in message
news:11**********************@l75g2000hse.googlegr oups.com...
Hi

I am developing an application in C#. The application creates a
TCPListener object and listens to (incoming) data on a particular
port. A simulator hardware writes data to this port. My application
reads the data and process it and generates some results for display.
...
The hardware is expected to write data in multiple of 4 bytes. If the
number of bytes written to the port is not multiple of 4 then it is
error condition. I am observing that sometimes the application does
not recieve the data of size which is multipe of 4. I am believing
that the hardware is producing correct application data. However,
there is a synchronisation issue for the software application. Before
the previous read is complete, the hardware seems to write new data.
Is this possible? If yes, then how does windows socket mechanism
handle it? Does it buffer the new data internally and then make it
....

Hi,
You should not count on sockets preserving packet sizes that you write. When
you write to socket, it is buffered by OS, then break into packet by TCP/IP
stack. Bottom line, if you send 100 bytes, don't count you'll receive
exactly 100 byte is one receive call on the other side. It can be 25, 40,
35, or even 100 if sender does multiple send calls fast (it will be joined
in one packet and sent to other side). No gurantees except that byte order
is preserved.

Regards,
Goran
Mar 23 '07 #2
Hi,

"Amit" <am********@yahoo.comwrote in message
news:11**********************@l75g2000hse.googlegr oups.com...
Hi
The TCPListener object waits for incoming data in a background thread.
In this kind of app I would suggest you to make it async.
The amount of data that is being written is large (around 100 KBytes
in one go). The thread listening for incoming data does not do much
processing. It allocates a buffer of large enough size and waits for
some data to be written on the port (TCPListener.Read() ). Once the
data arrives, it resizes the buffer to the size of the data written
and enqueues it in a Queue object.
Why do you "reset" your buffer?
How did you set your original buffer size?
how do you know if the amount of data you received was the same amount of
data sent? (it may get splitted in the way)
The hardware is expected to write data in multiple of 4 bytes. If the
number of bytes written to the port is not multiple of 4 then it is
error condition.
How you know you got the entire sent data? and not just part of it
>Can anyone explain how the underlying windows
socket mechanism work when there is a simultaneous read/write to an
application port?
The sending of data is not a sync'ed operation you read what is ready. It's
the protocol you define over the TCP connection the one that define how the
data is interpreted. Some protocols send a command like a ftp get. and then
it first receive the size of the file being downloaded, in this way the
client knows when to expect more data.
Mar 23 '07 #3
Amit wrote:
Once the
data arrives, it resizes the buffer to the size of the data written
and enqueues it in a Queue object.
Is access to the Queue synchronized (i.e. mutually exclusive)?
It then sets an AutoResetEvent to
which other thread is waiting. (That thread then dequeues the data and
processes it).
I wouldn't use an AutoResetEvent if I were you. If the dequeue thread
hasn't finished processing the last bit of data and hasn't yet waited on
the AutoResetEvent, then it will miss the notification and deadlock.

Consider using Monitor.Pulse and Monitor.Wait instead, very roughly like
this:

// Dequeue thread
for (;;)
{
for (;;)
lock (_queue)
{
if (_queue.Count 0)
{
data = _queue.Dequeue();
break;
}
Monitor.Wait(_queue);
}
// process data
}

Consider using an "end of data" item in the queue to communicate thread
shutdown.

// Enqueue thread, received data
lock (_queue)
{
_queue.Enqueue(data);
Monitor.Pulse(_queue);
}
The hardware is expected to write data in multiple of 4 bytes. If the
number of bytes written to the port is not multiple of 4 then it is
error condition.
Note that TCP is a stream protocol, not a packet protocol, so you aren't
guaranteed to receive multiples of 4 bytes, or the same sized buffers as
the sending side. For robust behaviour, you should consider processing
Length / 4 packets at a time, saving the sundry for the next receive.
>I am observing that sometimes the application does
not recieve the data of size which is multipe of 4. I am believing
that the hardware is producing correct application data. However,
there is a synchronisation issue for the software application. Before
the previous read is complete, the hardware seems to write new data.
TCP & networking can have buffers anywhere along the stack. The sender
is only blocked if it's out of buffer space or has run up against the
limit of the TCP window. It does not have to wait for the receiver to
read what it just sent.
If yes, then how does windows socket mechanism
handle it? Does it buffer the new data internally and then make it
available to the application once the previous read is over?
Assuming blocking sockets:

The sender can continue to send until something in the stack can't take
it, at which point it will block. By "something can't take it", I mean
either there isn't buffer space, or (more likely, if the receiver is
slow) the TCP window limit is hit. The TCP window is basically the
amount of IP packets the sender can send to the receiver before
receiving acknowledgement of sent packets.

The receiver will continue to receive data in the order it was sent. If
no data is ready, it will block. If the connection is closed by either
end, a call to receive will return with 0 bytes read.

-- Barry

--
http://barrkel.blogspot.com/
Mar 23 '07 #4
On Mar 23, 6:48 am, Barry Kelly <barry.j.ke...@gmail.comwrote:
Amit wrote:
Once the
data arrives, it resizes the buffer to the size of the data written
and enqueues it in a Queue object.

Is access to the Queue synchronized (i.e. mutually exclusive)?
It then sets an AutoResetEvent to
which other thread is waiting. (That thread then dequeues the data and
processes it).

I wouldn't use an AutoResetEvent if I were you. If the dequeue thread
hasn't finished processing the last bit of data and hasn't yet waited on
the AutoResetEvent, then it will miss the notification and deadlock.

Consider using Monitor.Pulse and Monitor.Wait instead, very roughly like
this:

// Dequeue thread
for (;;)
{
for (;;)
lock (_queue)
{
if (_queue.Count 0)
{
data = _queue.Dequeue();
break;
}
Monitor.Wait(_queue);
}
// process data

}

Consider using an "end of data" item in the queue to communicate thread
shutdown.

// Enqueue thread, received data
lock (_queue)
{
_queue.Enqueue(data);
Monitor.Pulse(_queue);

}
The hardware is expected to write data in multiple of 4 bytes. If the
number of bytes written to the port is not multiple of 4 then it is
error condition.

Note thatTCPis a stream protocol, not a packet protocol, so you aren't
guaranteed to receive multiples of 4 bytes, or the same sized buffers as
the sending side. For robust behaviour, you should consider processing
Length / 4 packets at a time, saving the sundry for the next receive.
I am observing that sometimes the application does
not recieve the data of size which is multipe of 4. I am believing
that the hardware is producing correct application data. However,
there is a synchronisationissuefor the software application. Before
the previous read is complete, the hardware seems to write new data.

TCP& networking can have buffers anywhere along the stack. The sender
is only blocked if it's out of buffer space or has run up against the
limit of theTCPwindow. It does not have to wait for the receiver to
read what it just sent.
If yes, then how does windows socket mechanism
handle it? Does it buffer the new data internally and then make it
available to the application once the previous read is over?

Assuming blocking sockets:

The sender can continue to send until something in the stack can't take
it, at which point it will block. By "something can't take it", I mean
either there isn't buffer space, or (more likely, if the receiver is
slow) theTCPwindow limit is hit. TheTCPwindow is basically the
amount ofIPpackets the sender can send to the receiver before
receiving acknowledgement of sent packets.

The receiver will continue to receive data in the order it was sent. If
no data is ready, it will block. If the connection is closed by either
end, a call to receive will return with 0 bytes read.

-- Barry

--http://barrkel.blogspot.com/
Thanks for all replies. I now understand that the number of bytes
received in the buffer can be anything and I need to handle '4 byte
long packet thing' inside my application. So if the number of packets
received are not multiple of 4, i need to cache additional bytes
locally and prepend to the the next lot of the data that I will
receive.

Now there is one issue of the buffer size. I dont know how much data
is going to be written in one shot. So how much buffer should I
allocate for receiving data? From what I understand from above, I
think I need not worry about this. If the the buffer space is not
sufficient, then the data write (from the hardware to my application
buffer) will be blocked and I will receive the data in next cycle. Is
this true?

Thanks and best regards
Amit Dedhia

Mar 26 '07 #5
On Mon, 26 Mar 2007 10:09:45 -0700, Amit <am********@yahoo.comwrote:
[...]
Now there is one issue of the buffer size. I dont know how much data
is going to be written in one shot. So how much buffer should I
allocate for receiving data?
It depends, but typically 4K or 8K is a pretty decent size for your
receive buffer. That's large enough that assuming you can receive the
data fast enough, you should generally be able to clear out the network
driver buffer with each receive, without wasting too much space (of
course, these days you could probably make your buffer even larger without
it hurting things too much :) ).

For very low bandwidth applications, it may be sufficient to provide a
buffer no larger than the largest logical data group you expect to have,
even if that's just a hundred bytes (or even less). You won't read the
data from the network driver efficiently, but it will be good enough as
long as data isn't actually coming in very fast, and it can save you the
hassle of dealing with yet another buffer in your code (you can just
allocate a buffer for the logical data group itself, filling directly it
as you go along with calls to the receiving method).
From what I understand from above, I
think I need not worry about this. If the the buffer space is not
sufficient, then the data write (from the hardware to my application
buffer) will be blocked and I will receive the data in next cycle. Is
this true?
That is true. However, keep in mind that it will affect efficiency. The
more time you have to call the network driver (via .NET Socket class,
Winsock, whatever), the lower your maximum bandwidth. Also, if you don't
receive data fast enough, then it's a negative feedback loop because the
sender may wind up having to pause or resend data, which further slows
things down.

Again, for low bandwidth applications, this isn't a concern but if you
have a need for efficiency, you should buffer receives yourself into a
large enough buffer to ensure that the network driver is always able to
receive new data from any senders.

Pete
Mar 26 '07 #6

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

Similar topics

21
by: Lasher | last post by:
Hi, I have clients using an application that allows users to change their passwords. The application uses the 'ALTER USER xxx IDENTIFIED BY.....' command. What I need to do is use Oracle to...
5
by: Bill Davidson | last post by:
Hello All: I've got a question about synchronization requiremements in a C# worker thread procedure that, among other things, sinks events from outside sources. I realize the worker thread will...
1
by: Bill Davidson | last post by:
(RESEND: I added a little more code to the sample for clarity) Hello All: I've got a question about synchronization requiremements in a C# worker thread procedure that, among other things,...
9
by: Abhishek Srivastava | last post by:
Hello All, In IIS 6.0 We have a concept of worker processes and application pools. As I understand it, we can have multiple worker process per appliction pool. Each worker process is dedicated...
2
by: Joel Vazquez | last post by:
Visual Basic.NET Application RunTime Crashes and Stalls Im a newbie if you could say in .NET ive been working with it the past 3 months and have done lots of things with it, without any prior...
11
by: Olie | last post by:
This post is realy to get some opinions on the best way of getting fast comunication between multiple applications. I have scowered the web for imformation on this subject and have just found...
2
by: cristalink | last post by:
The below is perfectly OK in C++, but I wonder how safe is it C#. There are cases when one thread is writing to, another one is reading from the same variable. I don't want/need to synchronize the...
17
by: > Adrian | last post by:
I have converted a number of applications to enable them to work together on a network. I have been led to believe that I can do this as follows: FileStream fs = new FileStream(some code); while...
5
by: Amit | last post by:
Hi I am developing an application in C#. The application creates a TCPListener object and listens to (incoming) data on a particular port. A simulator hardware writes data to this port. My...
4
by: Dave | last post by:
I have a global.asax file with Application_Start defined and create some static data there and in another module used in the asp.net application and I realize that static data is shared amongst...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...
0
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...
0
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,...
0
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...

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.