473,378 Members | 1,555 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,378 software developers and data experts.

TCP buffer splitting question ?

At the TCP server side I'm using:

///////////////////////////////////////////////////////////////////////////////
IPAddress DEFAULT_SERVER = IPAddress.Parse("127.0.0.1");
IPEndPoint ipNport = new IPEndPoint(DEFAULT_SERVER, 31001);
TcpListener m_server = new TcpListener(ipNport);

while( true )// For ever for this example
{
Socket m_clientSocket = m_server.AcceptSocket();
m_clientSocket.SetSocketOption(SocketOptionLevel.S ocket,
SocketOptionName.ReceiveBuffer, 65535);
Thread m_clientListenerThread = new Thread(new
ThreadStart(SocketListenerThreadStart));
m_clientListenerThread.Start();
}

private void SocketListenerThreadStart()
{
int size = 0;
byte [] byteBuffer = new byte[131072];// 128 Kilobyte.

while( true )// For ever for this example
{
size = m_clientSocket.Receive(byteBuffer);
}
}
///////////////////////////////////////////////////////////////////////////////

And a the client side:

///////////////////////////////////////////////////////////////////////////////
Thread m_clientThread = new Thread( new ThreadStart(ClientThreadStart) );
m_clientThread.Start();

private void ClientThreadStart()
{
Socket clientSocket = null;
int blockSize = 65535; // 64 KByte - 1 byte

IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 31001);
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
clientSocket.SetSocketOption(SocketOptionLevel.Soc ket,
SocketOptionName.SendBuffer, 65535);

clientSocket.Connect(ep);

byte [] rowData = new byte[ 1024 * 1024 ];
int blockCount = rowData.Length/blockSize + ((rowData.Length % blockSize
== 0) ? 0 : 1);

// Transmitting the buffer in blocks.
int length, sentSize;
for( i=0; i < blockCount ; ++i )
{
if( i < (blockCount - 1) )
{
length = blockSize;
}
else
{
length = rowData.Length - (i * blockSize);
}
sentSize = clientSocket.Send(rowData, i*blockSize, length,
System.Net.Sockets.SocketFlags.None);

if( sentSize < length )
{
// ERROR ?!
}
}
clientSocket.Close();
}
///////////////////////////////////////////////////////////////////////////////

The Send at the client side always return the same size that I asked for,
BUT the Receive on the server side almost all the time return size of smaller
size.
Is that how it should work? Why the receive socket does not buffer as I
asked (65535) ?
Can I improve it?

--
Thanks
Sharon
Nov 17 '05 #1
2 2064

"Sharon" <Sh****@discussions.microsoft.com> wrote in message
news:71**********************************@microsof t.com...
At the TCP server side I'm using:

///////////////////////////////////////////////////////////////////////////////
IPAddress DEFAULT_SERVER = IPAddress.Parse("127.0.0.1");
IPEndPoint ipNport = new IPEndPoint(DEFAULT_SERVER, 31001);
TcpListener m_server = new TcpListener(ipNport);

while( true )// For ever for this example
{
Socket m_clientSocket = m_server.AcceptSocket();
m_clientSocket.SetSocketOption(SocketOptionLevel.S ocket,
SocketOptionName.ReceiveBuffer, 65535);
Thread m_clientListenerThread = new Thread(new
ThreadStart(SocketListenerThreadStart));
m_clientListenerThread.Start();
}

private void SocketListenerThreadStart()
{
int size = 0;
byte [] byteBuffer = new byte[131072];// 128 Kilobyte.

while( true )// For ever for this example
{
size = m_clientSocket.Receive(byteBuffer);
}
}
///////////////////////////////////////////////////////////////////////////////

And a the client side:

///////////////////////////////////////////////////////////////////////////////
Thread m_clientThread = new Thread( new ThreadStart(ClientThreadStart) );
m_clientThread.Start();

private void ClientThreadStart()
{
Socket clientSocket = null;
int blockSize = 65535; // 64 KByte - 1 byte

IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 31001);
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
clientSocket.SetSocketOption(SocketOptionLevel.Soc ket,
SocketOptionName.SendBuffer, 65535);

clientSocket.Connect(ep);

byte [] rowData = new byte[ 1024 * 1024 ];
int blockCount = rowData.Length/blockSize + ((rowData.Length % blockSize
== 0) ? 0 : 1);

// Transmitting the buffer in blocks.
int length, sentSize;
for( i=0; i < blockCount ; ++i )
{
if( i < (blockCount - 1) )
{
length = blockSize;
}
else
{
length = rowData.Length - (i * blockSize);
}
sentSize = clientSocket.Send(rowData, i*blockSize, length,
System.Net.Sockets.SocketFlags.None);

if( sentSize < length )
{
// ERROR ?!
}
}
clientSocket.Close();
}
///////////////////////////////////////////////////////////////////////////////

The Send at the client side always return the same size that I asked for,
BUT the Receive on the server side almost all the time return size of
smaller
size.
Is that how it should work? Why the receive socket does not buffer as I
asked (65535) ?
Can I improve it?

--
Thanks
Sharon


NO you can't control this, this is how TCP/IP works. It's a streaming
protocol, your messages are put in message segments (88 min. up to ~1500
bytes max.) and segments are sent over the wire until a whole window is sent
after which the sender waits for an ACK, the receiving end will pack
segments and push them up the stack to your application, now when your
application is reading from the socket at a faster pace then the data
arrival, the TCP stack will deliver the actual received data as present in
it's internal buffers.
This is why I told you before that you might be wasting memory by allocating
large application buffers, you won't be able to receive let's say 1MB of
data in one Receive unless you are spending much time between receives. What
you should do is read the data as fast as you can and leave the rest to the
TCP/IP stack (Winsock, AFD kernel, NDIS driver etc.), if you need to handle
the data in between receives you could opt for an asynchronous design, as
such you can optimize your resources by reading from a socket while another
thread processes the data.
Some more remarks: - the size of sent bytes at the API level is the amount
accepted by the socket layer (the top of the stack), it's by no way the
amount physically transmitted to the other end.
- When I'm refering to the other end, you should think of routers and
switches etc, these are the intermediate end-points and they play also an
important role in the message delivery, they can fragment the data even
further, or restrict the bandwidth consumption.

Willy.


Nov 17 '05 #2
Thanks, I'm more calm thanks to your info.

Now I have encountered with a new and most disturbing problem. After
implementing all advices and knowledge I found in here I moved on and found
the following problem:

I have cases (too many of them) that result in data loss.
Some inforamation on my test configuration:
I have to PC's which are the same (Dell Dimension 2400).
PC1 is the tcp server, PC2 is the tcp client, they two configured to 65535
bytes tco buffer/window, and working in synchronous manner while for each
client the server start a dedicated thread.
The client send the data size in the first block and this way the server
knows when to stop processing the data from this client by accumulating the
retuned valued from the Socket.Receive(..) till it gets to the size received
in the first block.

When the server is handling a single client, no data is lost. But when I
switch the PC's so PC2 is the server and PC1 is the client, data is lost
causing the server to keep on waiting on the Socket.Receive(..) while the
client is done.

When the server (on PC1) is handling several clients (multiple threads
generated in PC2) again data is lost and some of the clients data is missing
in the server side again causing the server to keep on waiting on the
Socket.Receive(..) while all clients are done sending all their data.

I'm really don't know how fix that or what am I doing wrong.

Any advice will be more then welcome.
--------
Thanks
Sharon
Nov 17 '05 #3

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

Similar topics

3
by: somaBoy MX | last post by:
I'm building a site where I need to pull very large blocks from a database. I would like to make navigation a little more user friendly by splitting text in pages which can then be navigated. I...
7
by: qwweeeit | last post by:
Hi all, I am writing a script to visualize (and print) the web references hidden in the html files as: '<a href="web reference"> underlined reference</a>' Optimizing my code, I found that an...
3
by: Rakesh | last post by:
Hi, I was 'googling' to look out for some ways of optimizing the code and came across this term - 'hot / cold splitting'. In short, the discussion is about splitting heavily accessed ( hot )...
6
by: nwheavyw8 | last post by:
I am currently trying to write a simple PHP script that will split an uploading file up into 500kb "chunks", then read and concatenate them back together when accessed for download. I can't seem...
1
by: Andy Britcliffe | last post by:
Hi I'm faced with the situation where I could have a single physical file that could contain multiplie XML documents e.g file.txt contains the following: <?xml version="1.0"...
6
by: Earl Anderson | last post by:
I have a A97/XP applet I've developed for my own use in my department. My boss "suggests" that since I built it, I share it with and instruct the other 6 members of my department on its use. I've...
20
by: Ed | last post by:
I am running Access 2002 and just ran the built in Access wizard for splitting a database into a back end (with tables) and front end (with queries, forms, modules, etc.). After running the...
13
by: Sharon | last post by:
I'm using TcpClient and getting the Stream by: TcpClient tcpclnt = new TcpClient(); . . . Stream stm = tcpclnt.GetStream(); Now, when I'm trying to send a big buffer via stm.Write(...) I get an...
331
by: Xah Lee | last post by:
http://xahlee.org/emacs/modernization.html ] The Modernization of Emacs ---------------------------------------- THE PROBLEM Emacs is a great editor. It is perhaps the most powerful and...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
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: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.