tags:

views:

86

answers:

3

hi.

I have created a TCP server. I am facing one problem. my TCP Server is not receiving data larger than 30000 bytes.

here is code to receive data

MAX_TCP_DATA = 64000

private void Process()
        {
            if (client.Connected == true)
            {
                log.InfoFormat("Client connected :: {0}", client.Client.RemoteEndPoint);
                Byte[] bytes = new Byte[MAX_TCP_DATA];
                String data = null;
                NetworkStream stream = client.GetStream();

                int i;

                try
                {
                    // Loop to receive all the data sent by the client.
                    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        // bytes contains received data in byte[].
                        // Translate data bytes to a UTF-8 string.
                        byte[] receivedBuffer = new byte[i];
                        Array.Copy(bytes, receivedBuffer, i);

                        if (log.IsDebugEnabled)
                        {
                            data = System.Text.Encoding.UTF8.GetString(receivedBuffer);
                            log.InfoFormat("Received MSG ::: " + data);
                        }

                        CommEventArgs comEventArg = new CommEventArgs();
                        comEventArg.data = receivedBuffer;
                        IPEndPoint remoteIPEndPoint = (IPEndPoint)client.Client.RemoteEndPoint;
                        comEventArg.srcAddress = remoteIPEndPoint.Address.ToString();
                        comEventArg.srcPort = remoteIPEndPoint.Port;
                        comEventArg.length = i;
                        this.OnDataReceived(comEventArg);
                    }
                }
                catch (Exception ex)
                {
                    log.InfoFormat("Client disconnected : {0}", client.Client.RemoteEndPoint);
                }
                finally
                {
                   client.Close();
                }
            }
        }

when i sent byte array of 40000. my TCP Server receives only 26280 bytes.

Please tell me where is the problem in receiving.

+4  A: 

The problem is that you can not receive packets of arbitrary size. I see nothing in your code that indicates stream negotiation. TCP is a stream protocol, with the lower level using packets because it has to. This means your sending data is split into arbitrary packets. The reciving end packet size is pretty much random (hocw much is in the buffer) and may not even translate into a proper UTF8 complete strong at all.

This:

while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)

Is not reading all data the client has sent, but all data the server has received. THis may not be complete.

You need to go into the documentation and acutally do your homework - i.e. read it.

It says:

The Read operation will read as much data as is available, up to the number of bytes specified by the size parameter.

Basically, at the moment there is no more data. It may be there a millisecond later. This is why you need to know how much data to read before processing it - either with your own packet structure (having a length flag for example in the first two bytes), or by using CLRLF to indicate end of line - so when you get one you know you can process all bytes before.

The simplistic approach you have here simply will not work, as data transfer is not instant. The Read method will read whatever is cached at the receiver, and you assume this is basically all.

At the same time, the while is not necessary, except for handling clsoed sockets. Again, the documentation helps:

If no data is available for reading, the NetworkStream.Read method will block until data is available.

So, there is no way this returns 0 except the underlying socket was closed (and then it should throw an excception). Because it will wait until (some) data arrives.

Hint: Reading documentation is not a superflous thing. In your case you assume a behavior that is clearly totally not there according to the documentation.

TomTom
any article link for working TCP Server. ??
Mohsan
Well, use MSDN docuemnation. THat really is all you need - at least this is how i learned how to program them.
TomTom
+1  A: 

In your while loop, you are not guaranteed to get more data than 64k at a time. Are you receiving 26280 on the first read in the loop, or in total for all reads?

Typically you would need to read the whole stream first, then see how many bytes you have

List<byte> allBytes = new List<byte>(MAX_TCP_DATA);
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
    allBytes.AddRange( allBytes.Take(i) );
}
Console.WriteLine(allBytes.Count);
string data = System.Text.Encoding.UTF8.GetString(allBytes.ToArray());
Mikael Svenson
+1  A: 

It looks like you are trying to read all data together at once. NetworkStream is not worked as you expected. You should read the stream in small chunks and copy to the recieved buffer if you want to get all the data you expected.

In your case, you probably get 13720 bytes at first iteration and 26280 bytes at the second. As i stated before, it should be better to read in small chunks such as 64/256/1024 bytes etc. (especially in a slow network environment).

orka
thansk. I solved the problem by reading in small chunks then combining all chunks to a large byte array..
Mohsan
strea.Read() method called multiple time depending on the data available on network stream
Mohsan
you can also use networkStream.DataAvailable flag to check if it has more data in an ongoing data transfer session.
orka