473,803 Members | 2,038 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

reading into the buffer

Say I want to arrange bytes in the internal buffer in a certain way. I
receive those bytes in the socket.

One solution is to read in socket in pieces:

byte[] buffer = new byte[65536];
int index = 0;
m_socket.Receiv e(buffer , 8, SocketFlags.Non e);
index += 8;
//read the rest of the message
//int msgLength is remaining number of bytes in the buffer
m_socket.Receiv e(buffer , index, msgLen - index,
SocketFlags.Non e);
Questions:

1. How to calculate msgLength ?
2. How to make this operation when reading data in asynchronously,
using BeginReceive()

Thanks
Oct 24 '08 #1
10 2115
On Fri, 24 Oct 2008 10:08:42 -0700, puzzlecracker <ir*********@gm ail.com>
wrote:
Say I want to arrange bytes in the internal buffer in a certain way. I
receive those bytes in the socket.

One solution is to read in socket in pieces:

byte[] buffer = new byte[65536];
int index = 0;
m_socket.Receiv e(buffer , 8, SocketFlags.Non e);
index += 8;
//read the rest of the message
//int msgLength is remaining number of bytes in the buffer
m_socket.Receiv e(buffer , index, msgLen - index,
SocketFlags.Non e);
Questions:

1. How to calculate msgLength ?
If by "remaining number of bytes in the buffer", you mean ready to be read
from the socket, the answer is "you don't". For the same reason that
using a method like Poll() or Select() cannot provide any guarantees about
what will happen when you actually try to read from the socket, there's no
reliable way to calculate the bytes yet unread in the socket buffer in a
way that will allow you to depend on the calculation in a later call to
Receive().

The best you can do is provide a buffer to Receive() that is just large
enough for the remaining bytes you expect to get for a given message (I'm
assuming that the data in the first eight bytes in some way allow you to
calculate that). Then just keep reading in a loop until you've read that
many bytes, decreasing the length you offer to Receive() with each
iteration to take into account the number of bytes read already.

That said, this is only something you should be doing if you don't need
efficient i/o. There's a lot of overhead going back and forth between
your code and the network buffers, and if there's a lot of data coming
through, you can wind up forcing the network driver to have to throw out
incoming data, and making the other end send it again.

A much better approach is for the network i/o code to always just read as
much data as it can, and let another layer of your code deal with parsing
that out into usable messages. Doing so won't actually necessarily
address the above question directly (after all, the network i/o layer is
probably still going to be delivering data as a stream), but it does shift
it into a domain where you have a bit more control.
2. How to make this operation when reading data in asynchronously,
using BeginReceive()
The same way you'd deal with any transition in design from synchronous to
asynchronous. State that is kept in local variables simply has to be
moved into instance variables that can be accessed as each network
operation completes.

Pete
Oct 24 '08 #2
On Oct 24, 1:36*pm, "Peter Duniho" <NpOeStPe...@nn owslpianmk.com>
wrote:
On Fri, 24 Oct 2008 10:08:42 -0700, puzzlecracker <ironsel2...@gm ail.com>*
wrote:
Say I want to arrange bytes in the internal buffer in a certain way. I
receive those bytes in the socket.
One solution is to read in socket in pieces:
* * * * * * byte[] buffer = new byte[65536];
* * * * * * int index = 0;
* * * * * * m_socket.Receiv e(buffer , 8, SocketFlags.Non e);
* * * * * * *index += 8;
* * * * * * //read the rest of the message
* * * * * * //int msgLength is remaining number of bytes inthe buffer
* * * * * * m_socket.Receiv e(buffer , index, msgLen - index,
SocketFlags.Non e);
Questions:
1. How to calculate *msgLength ?

If by "remaining number of bytes in the buffer", you mean ready to be read *
*from the socket, the answer is "you don't". *For the same reason that *
using a method like Poll() or Select() cannot provide any guarantees about *
what will happen when you actually try to read from the socket, there's no *
reliable way to calculate the bytes yet unread in the socket buffer in a *
way that will allow you to depend on the calculation in a later call to *
Receive().

The best you can do is provide a buffer to Receive() that is just large *
enough for the remaining bytes you expect to get for a given message (I'm*
assuming that the data in the first eight bytes in some way allow you to *
calculate that). *Then just keep reading in a loop until you've read that *
many bytes, decreasing the length you offer to Receive() with each *
iteration to take into account the number of bytes read already.

That said, this is only something you should be doing if you don't need *
efficient i/o. *There's a lot of overhead going back and forth between *
your code and the network buffers, and if there's a lot of data coming *
through, you can wind up forcing the network driver to have to throw out *
incoming data, and making the other end send it again.

A much better approach is for the network i/o code to always just read as*
much data as it can, and let another layer of your code deal with parsing*
that out into usable messages. *Doing so won't actually necessarily *
address the above question directly (after all, the network i/o layer is *
probably still going to be delivering data as a stream), but it does shift *
it into a domain where you have a bit more control.
2. How to make this operation when reading data in asynchronously,
using BeginReceive()

The same way you'd deal with any transition in design from synchronous to*
asynchronous. *State that is kept in local variables simply has to be *
moved into instance variables that can be accessed as each network *
operation completes.

Pete
Is there another .net group dedicated to networking issues related to
csharp and .net general?
Oct 24 '08 #3
On Fri, 24 Oct 2008 13:07:02 -0700, puzzlecracker <ir*********@gm ail.com>
wrote:
Is there another .net group dedicated to networking issues related to
csharp and .net general?
There are no networking issues related to C#. The API is
language-agnostic.

As far as a newsgroup specific to network code in .NET, none that I'm
aware of. However, note that -- as I've mentioned before -- to a large
extent these issues aren't even specific to .NET; they are either inherent
in networking generally, or in Winsock, on which the .NET networking API
is built.

If you want a newsgroup that is more specific to networking questions than
this one, you might try alt.winsock.pro gramming or
comp.os.ms-windows.program mer.tools.winso ck. There are other newsgroups
that are even more general than those, not even being specific to Winsock.

Pete
Oct 24 '08 #4
"puzzlecrac ker" <ir*********@gm ail.comwrote in message
news:52******** *************** ***********@f77 g2000hsf.google groups.com...
Say I want to arrange bytes in the internal buffer in a certain way. I
receive those bytes in the socket.

One solution is to read in socket in pieces:

byte[] buffer = new byte[65536];
int index = 0;
m_socket.Receiv e(buffer , 8, SocketFlags.Non e);
index += 8;
//read the rest of the message
//int msgLength is remaining number of bytes in the buffer
m_socket.Receiv e(buffer , index, msgLen - index,
SocketFlags.Non e);
Questions:

1. How to calculate msgLength ?
2. How to make this operation when reading data in asynchronously,
using BeginReceive()

Thanks
The receive funciton returns the number of bytes received. The actual
number received may be (and often is) less than the number of bytes
requested (what I consider to be a quirk of BSD sockets). Here is a small
example of some working code that receives the next 4 bytes from a socket
stream.

Byte[] headerBuffer = new Byte[ 4 ];
int bytesReceived = 0;
int bytesToReceive = 4;
while( bytesToReceive bytesReceived )
{
bytesReceived += clientSocket.Re ceive( headerBuffer,
bytesReceived,
bytesToReceive -
bytesReceived, SocketFlags.Non e );
}

The basic idea is to repeast receiving until the number of byte asked for
are received. The reeive function includes an offset into the buffer to
append received data to, which is conventient so you can just keep sending
the same base buffer address.

I can't help with BeginReceive. I've never used it. I usually run separate
send and receive threads. The send thread takes messages from a queue and
sends them out the socket, and the receive thread receives messages from a
socket and makes the available to a queue that is read from the rest of the
application.

Regards,
Steve
Oct 26 '08 #5
On Sun, 26 Oct 2008 12:45:26 -0700, Steve <no************ *@comcast.net>
wrote:
The receive funciton returns the number of bytes received. The actual
number received may be (and often is) less than the number of bytes
requested (what I consider to be a quirk of BSD sockets).
If by "quirk" you mean "essential part of the design of TCP", then yes. :)

The behavior isn't specific to BSD sockets (the API from which Winsock is
inherited). It's a fundamental part of TCP. TCP does not require that
the receiver be able to know how many bytes will be sent in a stream. In
many protocols, the sender simply sends bytes until it's done, and then
shuts down the connection. The receiver knows it's received the last byte
when the shutdown is indicated at the receiver's end (e.g. Receive()
returns 0 as the number of bytes read).

If Receive() always blocked until it'd filled the buffer passed to it,
then applications that use the end of the stream to know when the
transmission has been completed simply wouldn't work.

Even changing the API so that it only returned with a partially-filled
buffer at the end-of-stream wouldn't make sense, because another valid way
of terminating messages is with a delimiter (for example, sending
null-terminated strings). Again, the receiver doesn't have advance
knowledge of the number of bytes that will be sent, so requiring to
provide that information in the form of the buffer length wouldn't work.

Instead, with all of the socket-based APIs, the receiving function
(recv(), WSARecv(), Socket.Receive( ), NetworkStream.R ead(), etc.) will
always return as much data is _available_ at the time that the operation
can be completed, up to the size of the buffer passed in. It never waits
to try to fill the buffer, because that wait could be indeterminately
long, or even infinitely long.
Here is a small
example of some working code that receives the next 4 bytes from a socket
stream. [...]
Not counting the poor efficiency, code like that is fine if you know for
sure that you're going to get 4 bytes, and you know for sure that you
can't do anything useful with the data until you've received those 4 bytes.

But that's hardly a universal condition for network code. It's not
something one would want generally built into the network API itself, and
I don't really think that "quirk" is the right word to describe how TCP
and the APIs available to use it work.

Pete
Oct 26 '08 #6
"Peter Duniho" <Np*********@nn owslpianmk.comw rote in message
news:op******** *******@petes-computer.local. ..
On Sun, 26 Oct 2008 12:45:26 -0700, Steve <no************ *@comcast.net>
wrote:
[snip]
>
But that's hardly a universal condition for network code. It's not
something one would want generally built into the network API itself, and
I don't really think that "quirk" is the right word to describe how TCP
and the APIs available to use it work.

Pete
The behavior you describe (and the way the receive works) is what I would
have expected from non-blocking sockets. With non-blocking sockets I would
expect to use "select" if I want to wait for data to show up, which perits a
timeout, and then use recv to get whatever data is available.

With blocking sockets I would expect that if I say I want to receive 128
characters, then I know I am expecting 128 characters, and don't bother me
until they show up. I know that isn't the way it works, but that was the
behavior I was expecting before I learned how things really work.

In fact I think the API would be easier to use if I could say receive n
bytes of data, or timeout if no new data shows up for u milliseconds or the
entire message doesn't show up in v milliseconds.

But, we live with what we have... and it works.

Regards,
Steve
Oct 26 '08 #7
On Sun, 26 Oct 2008 18:47:41 -0700, Steve <no************ *@comcast.net>
wrote:
"Peter Duniho" <Np*********@nn owslpianmk.comw rote in message
news:op******** *******@petes-computer.local. ..
[snip]
>>
So, it's your assertion that only protocols which advertise the number
of
bytes to be received in advance should be allowed to be implemented
using
blocking sockets?

It would certainly be more intuitive.
It would be _more_ intuitive for the API's buffer-management semantics to
vary according to a completely unrelated aspect of the API? And in a way
that prevents entire classes of protocol implementations from ever being
implemented using one of the two basic i/o mechanisms offered by the API?

If that's what's intuitive to you, all I can say is that I'm so very glad
you're not in the business of designing the APIs I use. Suffice to say,
you are in a very tiny minority in your opinion of how sockets should have
been designed.
[...]
I don't buy the argument that "it wouldn't work at all if designed
without
the behaviour you say is a quirk".
Then disprove it. Show how the API would work if a blocking call to
receive data did not return until the buffer passed to it had filled, even
with protocols where the receiver has no way to know how many bytes to
expect.
If you had to wait on one call that
tells you when and how much data is available, and then do a recv call to
read that much data, it would work just as well as the existing recv.
First of all, semantically that's exactly what happens now, except you can
do it in a single call. Secondly, from a practical point of view, that
API wouldn't work at all, because there's no reliable way to query the
amount of data that's available and be guaranteed that data will _still_
be available when you try to receive it (in case you missed it earlier, I
refer to the Winsock Lame List link I provided previously:
http://tangentsoft.net/wskfaq/articles/lame-list.html).

The entire Internet is founded on some fundamental design choices about
how TCP/IP works, including the option of endpoints to drop received data
and force a retry if they become overloaded or otherwise need to clear
some buffer space. These very basic design choices affect a number of
things, including how an API like sockets _has_ to work.

You can rail against it if you like, but all you're going to do is make
yourself unhappy. The fact is, given the technology involved, there's
really no way that the sockets API could have been designed to work as you
want it to.

Pete
Oct 27 '08 #8
On Oct 24, 5:53*pm, "Peter Duniho" <NpOeStPe...@nn owslpianmk.com>
wrote:
On Fri, 24 Oct 2008 13:07:02 -0700, puzzlecracker <ironsel2...@gm ail.com>*
wrote:
Is there another .net group dedicated to networking issues related to
csharp and .net general?

There are no networking issues related to C#. *The API is *
language-agnostic.

As far as a newsgroup specific to network code in .NET, none that I'm *
aware of. *However, note that -- as I've mentioned before -- to a large*
extent these issues aren't even specific to .NET; they are either inherent *
in networking generally, or in Winsock, on which the .NET networking API *
is built.

If you want a newsgroup that is more specific to networking questions than *
this one, you might try alt.winsock.pro gramming or *
comp.os.ms-windows.program mer.tools.winso ck. *There are other newsgroups *
that are even more general than those, not even being specific to Winsock..

Pete
Thanks, I'm taking a dive into learning of winsock..
Oct 27 '08 #9
"Peter Duniho" <Np*********@nn owslpianmk.comw rote in message
news:op******** *******@petes-computer.local. ..
[snip]
The entire Internet is founded on some fundamental design choices about
how TCP/IP works, including the option of endpoints to drop received data
and force a retry if they become overloaded or otherwise need to clear
some buffer space. These very basic design choices affect a number of
things, including how an API like sockets _has_ to work.
Clearly you have the positon that anything other than the way things are
currently implented will not work.

I'll agree to disagree.

Regards,
Steve

You can rail against it if you like, but all you're going to do is make
yourself unhappy. The fact is, given the technology involved, there's
really no way that the sockets API could have been designed to work as you
want it to.

Pete

Oct 28 '08 #10

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

Similar topics

0
1926
by: travis ray | last post by:
Hi, I have an extension in which a file object is created in python and passed down to a c extension which attempts to read from it or write to it. Writing to the file pointer seems to work okay, but reading from it results in EBADF. It also causes python to crash on exit. I've attached the minimal (I think) c code, python code, build script, build log, and run log. Any and all help is greatly appreciated.
1
7059
by: fabrice | last post by:
Hello, I've got trouble reading a text file (event viewer dump) by using the getline() function... After 200 - 300 lines that are read correctly, it suddenly stops reading the rest of the file... Thank you to all of you who can help me with this one...
24
2767
by: Hendrik Schober | last post by:
Hi, I have a 'std::istream' and need to read its whole contents into a string. How can I do this? TIA; Schobi
19
10383
by: Lionel B | last post by:
Greetings, I need to read (unformatted text) from stdin up to EOF into a char buffer; of course I cannot allocate my buffer until I know how much text is available, and I do not know how much text is available until I have read it... which seems to imply that multiple reads of the input stream will be inevitable. Now I can correctly find the number of characters available by: |
1
6253
by: inkapyrite | last post by:
Hi all. I'm using ifstream to read from a named pipe but i've encountered an annoying problem. For some reason, the program blocks on reading an ifstream's internal buffer that's only half-filled. Only when the buffer becomes full does it resume execution. Here's my test code for reading from a pipe: //(compiled with g++ -std=c++98) //--------------------------------------------- #include <iostream>
50
5022
by: Michael Mair | last post by:
Cheerio, I would appreciate opinions on the following: Given the task to read a _complete_ text file into a string: What is the "best" way to do it? Handling the buffer is not the problem -- the character input is a different matter, at least if I want to remain within the bounds of the standard library.
21
13109
by: JoKur | last post by:
Hello, First let me tell you that I'm very new to C# and learning as I go. I'm trying to write a client application to communicate with a server (that I didn't write). Each message from the server is on one line (\r\n at end) and is formed as - each of which is seperated by a space. Arguments with spaces in them are enclosed in quotations. So, I'm able to open a connection to the server. When I send a message to
21
6397
by: EdUarDo | last post by:
Hi all, I'm not a newbie with C, but I don't use it since more than 5 years... I'm trying to read a text file which has doubles in it: 1.0 1.1 1.2 1.3 1.4 2.0 2.1 2.2 2.3 2.4 I'm doing this (it's only a test trying to achieve the goal...):
2
3243
by: =?Utf-8?B?VHJlY2l1cw==?= | last post by:
Hello, Newsgroupians: In regards to reading a stream, I know we use the Read() method. One could implement reading a stream using a while-loop. while (stream.Read(buffer, 0, buffer.Length) != 0) { // Process the buffer }
0
10309
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
10289
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
10068
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
9119
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
7600
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
5496
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5625
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4274
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2968
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.