Strange problem with System.Net.Sockets.TcpClient()

T

Torsten Brasch

Hi All and Happy New Year ;)

I have a very strange problem with System.Net.Sockets.TcpClient().
For some reason, the number of bytes I can receive is limited to 5460 bytes.
I made sure that the server really sends everything I expect it to send. I
am actually sending XML messages and this limit is a pain in the ...

Here is the code:
--------------------------------------------------------------------------
Dim tcpclient As New System.Net.Sockets.TcpClient()
tcpclient.Connect(Server_IP, portNumber)

Dim NWStream As NetworkStream = tcpclient.GetStream
Dim bytesToSend As Byte() = Encoding.ASCII.GetBytes(pInText)

'---send the text
NWStream.Write(bytesToSend, 0, bytesToSend.Length)

'---read back the text
Dim bytesToRead(tcpclient.ReceiveBufferSize) As Byte

' HERE IS THE PROBLEM - numBytesRead for some reason is limited to 5460
bytes
Dim numBytesRead As Int32 = NWStream.Read(bytesToRead, 0,
tcpclient.ReceiveBufferSize)Result = Encoding.ASCII.GetString(bytesToRead,
0, numBytesRead)

tcpclient.Close()

--------------------------------------------------------------------------

I would very much appreciate if somebody had a clue of what is going on
here.

Thanks,
Torsten
 
C

Chris Botha

Actually you have to read until the bytes read = 0 (or until an error
occurs), and concatenate each segment read, building up the message.
Sockets behavior can be strange, depending on the environment conditions
(like machine busy, network flakey, etc) and in some cases you may receive
only a couple of hundred bytes of the total message with one read.
The NetworkStream class may have some magic built in that I don't know
about, so try adjusting the ReceiveBufferSize, but I won't bet on it.
 
T

Torsten Brasch

I've set ReceiveBufferSize to 32768, just for a test - no change. In fact,
in my example code, the system sets it to 8192 by default. I just did a few
more tests, as soon as I send 5461 bytes, that 1 additional byte is lost. I
always just get 5460 bytes out of the stream.
 
T

Torsten Brasch

Ok, I think I solved it:

Instead of
Dim numBytesRead As Int32 = NWStream.Read(bytesToRead, 0,
tcpclient.ReceiveBufferSize)

I am doing this now:

' Ok, let's try with reading every single byte
Dim n As Int32 = 0
Dim i As Int32 = 1

While i <> 0
i = NWStream.Read(bytesToRead, n, 1)
n += 1
Response.Write(CStr(i) + "|" + CStr(n) + "<br>")
Response.Flush()
End While

This actually works. I get the full data now BUT if I send more than 8K
(8192 bytes), it throws an exception saying 'index out of range".

So that is the ReceiveBuffer that still is 8K even though I am sending more
than that.
The MS documentation makes it clear though: You don't have to worry about
the size of ReceiveBuffer, the system dynamically increases it - well,
obviously NOT ;(

I can set it manually, let's say to 32768 bytes - but I am confident that
one of my users will hit that limit as well - would have been so nice to
have it increased dynamically.

Thanks for your hint with reading until the result is ZERO!!! ;)

Thanks,
Torsten
 
C

Chris Botha

It should not crash and don't read 1 byte at a shot, it is too slow, read at
least 5400 (if the max transfer size is 5460 as per your previous message).
It works even if the message is shorter, because you look at the bytes read
count after the read and not the size given as parameter (the size given as
parameter depicts your data buffer size).
Look at the example in the "NetworkStream.Read" in the documentation,
they read blocks of 1024 bytes and build the message in a loop.
 
F

Feroze [MSFT]

Your read loop is incorrect. You are assuming that all the data will be
available in the first read. THis is not true, as TCP is a stream based
transfer, and record boundaries are not supported.

I am assuming that the data coming back is ASCII text. So, you an code your
Read loop as follows: (in C# syntax)

MemoryStream ms = new MemoryStream();
byte [] bytesToRead = new byte[tcpclient.ReadBufferSize];
int numBytesRead = -1;

while(true) {
try {
numBytesRead = NWStream.Read((bytesToRead, 0,
tcpclient.ReceiveBufferSize);
if(numBytesRead > 0)
ms.Write(bytesToRead,0,numBytesRead);
else
break;
} catch {
throw;
}
}

ms.Seek(0,SeekOrigin.Begin);
StreamReader sr = new StreamReader(ms,Encoding.ASCII);
Result = sr.ReadToEnd();
sr.Close();
ms.Close();

NWStream.Close();
tcpclient.Close();


--
Remove "user" from the email address to reply to the author.

This posting is provided "AS IS" with no warranties, and confers no rights

Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top