none
Asyncronous TCP/IP Client/Server

    Question

  • I was wondering how I can receive data that is larger than 8192 Bytes. I am sending Byte Arrays over TCP/IP that are larger than 8192. The problem is I can't get all the data accross. Cann someone help me. Here is the code for the client/Server

    Server

    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    namespace ClassLibrary
    {
        /// <summary>
        /// An Asynchronous TCP Server that makes use of system managed threads
        /// and callbacks to stop the server ever locking up.
        /// </summary>
        public class Server
        {
            private TcpListener tcpListener;
            private List<Client> clients;
            /// Occurs when the client connects to the server.
            public event EventHandler Connected;
            /// Occurs when the client disconnects from the server.
            public event EventHandler Disconnected;
            /// <summary>
            /// Constructor for a new server using an IPAddress and Port
            /// </summary>
            /// <param name="localaddr">The Local IP Address for the server.</param>
            /// <param name="port">The port for the server.</param>
            public Server(IPAddress localaddr, int port)
                : this()
            {
                tcpListener = new TcpListener(localaddr, port);
            }
            /// <summary>
            /// Constructor for a new server using an end point
            /// </summary>
            /// <param name="localEP">The local end point for the server.</param>
            public Server(IPEndPoint localEP)
                : this()
            {
                tcpListener = new TcpListener(localEP);
            }
            /// <summary>
            /// Private constructor for the common constructor operations.
            /// </summary>
            private Server()
            {
                this.Encoding = Encoding.Default;
                this.clients = new List<Client>();
            }
            /// <summary>
            /// The encoding to use when sending / receiving strings.
            /// </summary>
            public Encoding Encoding 
            { 
                get; 
                set; 
            }
            /// <summary>
            /// An enumerable collection of all the currently connected tcp clients
            /// </summary>
            public IEnumerable<TcpClient> TcpClients
            {
                get
                {
                    foreach (Client client in this.clients)
                    {
                        yield return client.TcpClient;
                    }
                }
            }
            /// <summary>
            /// Starts the TCP Server listening for new clients.
            /// </summary>
            public void Start()
            {
                this.tcpListener.Start();
                this.tcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
            }
            /// <summary>
            /// Stops the TCP Server listening for new clients and disconnects
            /// any currently connected clients.
            /// </summary>
            public void Stop()
            {
                this.tcpListener.Stop();
                lock (this.clients)
                {
                    foreach (Client client in this.clients)
                    {
                        client.TcpClient.Client.Disconnect(false);
                    }
                    this.clients.Clear();
                }
            }
            /// <summary>
            /// Writes a string to a given TCP Client
            /// </summary>
            /// <param name="tcpClient">The client to write to</param>
            /// <param name="data">The string to send.</param>
            public void Write(TcpClient tcpClient, string data)
            {
                byte[] bytes = this.Encoding.GetBytes(data);
                Write(tcpClient, bytes);
            }
            /// <summary>
            /// Writes a string to all clients connected.
            /// </summary>
            /// <param name="data">The string to send.</param>
            public void Write(string data)
            {
                foreach (Client client in this.clients)
                {
                    Write(client.TcpClient, data);
                }
            }
            /// <summary>
            /// Writes a byte array to all clients connected.
            /// </summary>
            /// <param name="bytes">The bytes to send.</param>
            public void Write(byte[] bytes)
            {
                foreach (Client client in this.clients)
                {
                    Write(client.TcpClient, bytes);
                }
            }
            /// <summary>
            /// Writes a byte array to a given TCP Client
            /// </summary>
            /// <param name="tcpClient">The client to write to</param>
            /// <param name="bytes">The bytes to send</param>
            public void Write(TcpClient tcpClient, byte[] bytes)
            {
                NetworkStream networkStream = tcpClient.GetStream();
                networkStream.BeginWrite(bytes, 0, bytes.Length, WriteCallback, tcpClient);
            }
            /// <summary>
            /// Callback for the write opertaion.
            /// </summary>
            /// <param name="result">The async result object</param>
            private void WriteCallback(IAsyncResult result)
            {
                TcpClient tcpClient = result.AsyncState as TcpClient;
                NetworkStream networkStream = tcpClient.GetStream();
                networkStream.EndWrite(result);
            }
            /// <summary>
            /// Callback for the accept tcp client opertaion.
            /// </summary>
            /// <param name="result">The async result object</param>
            private void AcceptTcpClientCallback(IAsyncResult result)
            {
                TcpClient tcpClient = tcpListener.EndAcceptTcpClient(result);
                byte[] buffer = new byte[tcpClient.ReceiveBufferSize];
                Client client = new Client(tcpClient, buffer);
                lock (this.clients)
                {
                    this.clients.Add(client);
                }
                NetworkStream networkStream = client.NetworkStream;
                networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
                tcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
                if (Connected != null)
                {
                    Connected(this, new EventArgs());
                }
            }
            /// <summary>
            /// Callback for the read opertaion.
            /// </summary>
            /// <param name="result">The async result object</param>
            private void ReadCallback(IAsyncResult result)
            {
                Client client = result.AsyncState as Client;
                if (client == null)
                {
                    return;
                }
                NetworkStream networkStream = client.NetworkStream;
                int read = networkStream.EndRead(result);
                if (read == 0)
                {
                    lock (this.clients)
                    {
                        this.clients.Remove(client);
                        return;
                    }
                }
                //string data = this.Encoding.GetString(client.Buffer, 0, read);
                //Do something with the data object here.
                networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
            }
        }
        /// <summary>
        /// Internal class to join the TCP client and buffer together 
        /// for easy management in the server
        /// </summary>
        internal class Client
        {
            /// <summary>
            /// Constructor for a new Client
            /// </summary>
            /// <param name="tcpClient">The TCP client</param>
            /// <param name="buffer">The byte array buffer</param>
            public Client(TcpClient tcpClient, byte[] buffer)
            {
                if (tcpClient == null)
                {
                    throw new ArgumentNullException("tcpClient");
                }
                if (buffer == null)
                {
                    throw new ArgumentNullException("buffer");
                }
                this.TcpClient = tcpClient;
                this.Buffer = buffer;
            }
            /// <summary>
            /// Gets the TCP Client
            /// </summary>
            public TcpClient TcpClient 
            {
                get;
                private set; 
            }
            /// <summary>
            /// Gets the Buffer.
            /// </summary>
            public byte[] Buffer
            { 
                get; 
                private set; 
            }
            /// <summary>
            /// Gets the network stream
            /// </summary>
            public NetworkStream NetworkStream 
            {
                get
                { 
                    return TcpClient.GetStream(); 
                } 
            }
        }
    }

    Client

    using System;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    namespace ClassLibrary
    {    
        public class AsyncClient
        {
            private IPAddress[] addresses;
            private int Port;
            private WaitHandle addressesSet;
            private TcpClient tcpClient;
            private int failedConnectionCount;
            /// Occurs when the client connects to the server.
            public event EventHandler Connected;
            /// Occurs when the client disconnects from the server.
            public event EventHandler Disconnected;
            /// <summary>
            /// Construct a new client from a known IP Address
            /// </summary>
            /// <param name="address">The IP Address of the server</param>
            /// <param name="port">The port of the server</param>
            public AsyncClient(IPAddress address, int port)
            {
                addresses = new[] { address };
                Port = port;
                this.tcpClient = new TcpClient();
                this.Encoding = Encoding.Default;
            }
            /// <summary>
            /// Construct a new client where multiple IP Addresses for
            /// the same client are known.
            /// </summary>
            /// <param name="addresses">The array of known IP Addresses</param>
            /// <param name="port">The port of the server</param>
            public AsyncClient(IPAddress[] addresses, int port)
            {
                this.addresses = addresses;
                Port = port;
                this.tcpClient = new TcpClient();
                this.Encoding = Encoding.Default;
            }
            /// <summary>
            /// Construct a new client where the address or host name of
            /// the server is known.
            /// </summary>
            /// <param name="hostNameOrAddress">The host name or address of the server</param>
            /// <param name="port">The port of the server</param>
            public AsyncClient(string hostNameOrAddress, int port)
            {
                addressesSet = new AutoResetEvent(false);
                Port = port;
                Dns.BeginGetHostAddresses(hostNameOrAddress, GetHostAddressesCallback, null);
                this.tcpClient = new TcpClient();
                this.Encoding = Encoding.Default;
            }
            /// <summary>
            /// Private constuctor called by other constuctors
            /// for common operations.
            /// </summary>
            /// <param name="port"></param>
            private AsyncClient(int port)
            {
                if (port < 0)
                {
                    throw new ArgumentException();
                }
                this.Port = port;
                this.tcpClient = new TcpClient();
                this.Encoding = Encoding.Default;
            }
            /// <summary>
            /// The endoding used to encode/decode string when sending and receiving.
            /// </summary>
            public Encoding Encoding 
            { 
                get; 
                set;
            }
            /// <summary>
            /// Attempts to connect to one of the specified IP Addresses
            /// </summary>
            public void Connect()
            {
                if (addressesSet != null)
                    //Wait for the addresses value to be set
                    addressesSet.WaitOne();
                //Set the failed connection count to 0
                Interlocked.Exchange(ref failedConnectionCount, 0);
                //Start the async connect operation
                tcpClient.BeginConnect(addresses, Port, ConnectCallback, null);
            }
            /// <summary>
            /// Writes a string to the network using the defualt encoding.
            /// </summary>
            /// <param name="data">The string to write</param>
            /// <returns>A WaitHandle that can be used to detect
            /// when the write operation has completed.</returns>
            public void Write(string data)
            {
                byte[] bytes = Encoding.GetBytes(data);
                Write(bytes);
            }
            /// <summary>
            /// Writes an array of bytes to the network.
            /// </summary>
            /// <param name="bytes">The array to write</param>
            /// <returns>A WaitHandle that can be used to detect
            /// when the write operation has completed.</returns>
            public void Write(byte[] bytes)
            {
                NetworkStream networkStream = tcpClient.GetStream();
                int CharCount = bytes.Length.ToString().Length;
                byte[] AllData = new byte[bytes.Length + CharCount + 1];
                AllData[0] = Convert.ToByte(CharCount);
                for (int i = 1; i <= CharCount.ToString().Length; i++)
                {
                    char c = CharCount.ToString()[i - 1];
                    AllData[i] = Convert.ToByte(c);
                }
                bytes.CopyTo(AllData, CharCount + 1);
                //Start async write operation
                networkStream.BeginWrite(bytes, 0, bytes.Length, WriteCallback, null);
            }
            /// <summary>
            /// Callback for Write operation
            /// </summary>
            /// <param name="result">The AsyncResult object</param>
            private void WriteCallback(IAsyncResult result)
            {
                NetworkStream networkStream = tcpClient.GetStream();
                networkStream.EndWrite(result);
            }
            /// <summary>
            /// Callback for Connect operation
            /// </summary>
            /// <param name="result">The AsyncResult object</param>
            private void ConnectCallback(IAsyncResult result)
            {
                try
                {
                    tcpClient.EndConnect(result);
                    if (this.Connected != null)
                    {
                        Connected(this, new EventArgs());
                    }
                }
                catch
                {
                    //Increment the failed connection count in a thread safe way
                    Interlocked.Increment(ref failedConnectionCount);
                    if (failedConnectionCount >= addresses.Length)
                    {
                        //We have failed to connect to all the IP Addresses
                        //connection has failed overall.
                        return;
                    }
                }
                //We are connected successfully.
                NetworkStream networkStream = tcpClient.GetStream();
                byte[] buffer = new byte[tcpClient.ReceiveBufferSize];
                //Now we are connected start asyn read operation.
                networkStream.BeginRead(buffer, 0, buffer.Length, ReadCallback, buffer);
            }
            /// <summary>
            /// Callback for Read operation
            /// </summary>
            /// <param name="result">The AsyncResult object</param>
            private void ReadCallback(IAsyncResult result)
            {
                int read;
                NetworkStream networkStream;
                try
                {
                    networkStream = tcpClient.GetStream();
                    read = networkStream.EndRead(result);
                }
                catch
                {
                    //An error has occured when reading
                    return;
                }
                if (read == 0)
                {
                    //The connection has been closed.
                    return;
                }
                byte[] buffer = result.AsyncState as byte[];
                string data = this.Encoding.GetString(buffer, 0, read);
                //Do something with the data object here.
                //Then start reading from the network again.
                networkStream.BeginRead(buffer, 0, buffer.Length, ReadCallback, buffer);
            }
            /// <summary>
            /// Callback for Get Host Addresses operation
            /// </summary>
            /// <param name="result">The AsyncResult object</param>
            private void GetHostAddressesCallback(IAsyncResult result)
            {
                addresses = Dns.EndGetHostAddresses(result);
                //Signal the addresses are now set
                ((AutoResetEvent)addressesSet).Set();
            }
        }
    }

    Tuesday, April 03, 2012 1:39 PM

Answers

  • I'm not sure about your write code.  It seems overly complex.  If you want to write a byte array then you can do something like this:

    private void WriteData ( byte[] data, Stream stream )
    {
        using (var writer = new BinaryWriter(stream))
        {
            //Message header
           ...
          writer.Write(data.Length);  //Write as an Int32
    
          //Data
          writer.Write(data);
       };
    }
    
    private byte[] ReadData ( Stream stream )
    {
       using (var reader = new StreamReader(stream))
       {
          //Message header
          ...
          int length = reader.ReadInt32();
          
          var data = new byte[length];
          int currentPos = 0;
          int remaining = length;
          int read;
          do
          {
              read = reader.Read(data, currentPos, remaining);
              currentPos += read;
              remaining -= read;
          } while (read > 0);
       };
    }

    Ignoring error checking the above is reasonably close.  Be careful with Reader/Writer though as they auto-close the stream when they are disposed. If you don't want that then you either need to create your own Reader/Writer versions (I expose my via extension methods of the Stream class) or create a wrapper stream type that ignores close requests.  The wrapper stream is easier as you just defer all requests to the wrapped stream except disposal so the Reader/Writer is happy but I find extension methods on the Stream class cleaner.

    Michael Taylor - 4/3/2012
    http://msmvps.com/blogs/p3net

    • Marked as answer by brown71576 Tuesday, April 03, 2012 5:27 PM
    Tuesday, April 03, 2012 3:47 PM
  • I have worked through a solution

            /// <summary>
            /// Callback for the read opertaion.
            /// </summary>
            /// <param name="result">The async result object</param>
            private void ReadCallback(IAsyncResult result)
            {
                Client client = result.AsyncState as Client;
                if (client == null)
                {
                    return;
                }
                
                NetworkStream networkStream = client.NetworkStream;
       
                int BytesReceived = 0;
                int CurrentPosition = 0;
                // This will hold the actual payload. This array will not have the header
                // data that was send by the client
                Byte[] m_ReadBuffer = null;
                // Alaways will be null at this point
                if (m_ReadBuffer == null)
                {
                    // This will hold the number of bytes we need to read 
                    // in order to determine how big the packet is.
                    Byte[] SizeBuffer = new Byte[1];
                    // Get the 1st byte, this will tell us how many bytes to read
                    // in order to k now the size of the payload.
                    //
                    // Example: [4][8][2][0][0][...][n]
                    //
                    // [4] => read the next 4 bytes to get the actual size of the payload.
                    SizeBuffer[0] = client.Buffer[0];
                    // Initialize a new byte arrays that lets us know how big the payload is
                    // [8][2][0][0] => 8200 Bytes is the payload size.
                    Byte[] NewBuffer = new Byte[SizeBuffer[0]];
                    // Used to dim a BYte array for the payload size
                    string Temp = string.Empty;
                    // Get the Payload size
                    for (int i = 0; i < NewBuffer.Length; i++)
                    {
                        NewBuffer[i] = client.Buffer[i + 1];
                        Temp += NewBuffer[i].ToString();
                    }
                    int Size = Convert.ToInt32(Temp);
                    m_ReadBuffer = new Byte[Size];
                    // Store the first packet of data.
                    ReadElements(SizeBuffer.Length + NewBuffer.Length, client.Buffer, ref m_ReadBuffer, ref CurrentPosition);
                    // Total bytes received minus the header data
                    BytesReceived = client.Buffer.Length - (SizeBuffer.Length + NewBuffer.Length);
                }           
                // Now make sure we get all the data sent by the client
                while (BytesReceived != m_ReadBuffer.Length)
                {
                    // Get how many more bytes we need to have all data.
                    int Difference = m_ReadBuffer.Length - CurrentPosition;
                    // If its more than the default packets size, just read the whole packets
                    // else only read the number of bytes needed to get the rest of the data.
                    if (Difference > 8192)
                    {
                        Byte[] b = new Byte[8192];
                        BytesReceived = BytesReceived + networkStream.Read(b, 0, 8192);
                        ReadElements(0, b, ref m_ReadBuffer, ref CurrentPosition);
                    }
                    else
                    {
                        Byte[] b = new Byte[Difference];
                        try
                        {
                            BytesReceived = BytesReceived + networkStream.Read(b, 0, Difference);
                        }
                        catch (Exception Ex)
                        {
                            string Message = Ex.Message;
                        }
                        // Copy bytes to m_ReadBuffer starting at a specific position
                        ReadElements(0, b, ref m_ReadBuffer, ref CurrentPosition);
                    }                
                }
                int read = networkStream.EndRead(result);
                if (read == 0)
                {
                    lock (this.clients)
                    {
                        this.clients.Remove(client);
                        return;
                    }
                }
                //Here is where I will handle the data
                // Start listening for another transfer from the client.
                networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
            }
        }

    • Marked as answer by brown71576 Tuesday, April 03, 2012 5:27 PM
    Tuesday, April 03, 2012 5:26 PM

All replies

  • Just off the top of my head, the problem may be that all the data is being sent but it's being split up along the way. If that is the case, what you need to do is create a buffer for each client. Each message should have some sort of start flag and stop flag as well. Whenever you receive some data, you add it to the buffer and then check if you have a full message in the buffer. If you do, remove the message from the buffer and process it.
    Tuesday, April 03, 2012 1:51 PM
  • There's no arbitrary limit on the size of data sent across the wire.  The data is streamed so you can send any amount of data.  I've sent MBs of data before.

    What I suspect is happening is that you're only getting 8K because that is the default buffer size and you are only making one read call.  When reading data from a stream you must call the stream in a loop until all the data is read.  The data is always read in chunks so even if you send 20 bytes it might take a couple of reads depending upon network latency and errors.  Standard network reading code has you call the Read method until all the data you expect is read.  To facilitate this you generally have to precede each (logical) message with a header that specifies what you're sending and how much.  The message header is generally fixed size so the read code can read the header.  Once the header is read the reader knows how much more to read and then uses a loop to read until all the data is read.

    Michael Taylor - 4/3/2012
    http://msmvps.com/blogs/p3net

    Tuesday, April 03, 2012 1:53 PM
  • There's no arbitrary limit on the size of data sent across the wire.  The data is streamed so you can send any amount of data.  I've sent MBs of data before.

    What I suspect is happening is that you're only getting 8K because that is the default buffer size and you are only making one read call.  When reading data from a stream you must call the stream in a loop until all the data is read.  The data is always read in chunks so even if you send 20 bytes it might take a couple of reads depending upon network latency and errors.  Standard network reading code has you call the Read method until all the data you expect is read.  To facilitate this you generally have to precede each (logical) message with a header that specifies what you're sending and how much.  The message header is generally fixed size so the read code can read the header.  Once the header is read the reader knows how much more to read and then uses a loop to read until all the data is read.

    Michael Taylor - 4/3/2012
    http://msmvps.com/blogs/p3net


    I have attempted to do a while loop inside the

    ReadCallback on the server side but I can't ever get more than 8192 for some reason. I am testing this by sending a 8200 Byte array across. The first Bytes say how much to read for example. If I am sending a Payload of 8200 Bytes, I setup a header. The first byte being 4 which lets the server know to read the next 4 bytes to get the size of the payload the client is sending. So Byte[1] = 8, Byte[2] = 2, Byte[3] = 0, Byte[4] = 0, then Byte[5] to Byte[n] id the payload.

    If you have the time and could show me an example that would be nice.

    Regards,

    MIke

    Tuesday, April 03, 2012 2:32 PM
  • I'm not sure about your write code.  It seems overly complex.  If you want to write a byte array then you can do something like this:

    private void WriteData ( byte[] data, Stream stream )
    {
        using (var writer = new BinaryWriter(stream))
        {
            //Message header
           ...
          writer.Write(data.Length);  //Write as an Int32
    
          //Data
          writer.Write(data);
       };
    }
    
    private byte[] ReadData ( Stream stream )
    {
       using (var reader = new StreamReader(stream))
       {
          //Message header
          ...
          int length = reader.ReadInt32();
          
          var data = new byte[length];
          int currentPos = 0;
          int remaining = length;
          int read;
          do
          {
              read = reader.Read(data, currentPos, remaining);
              currentPos += read;
              remaining -= read;
          } while (read > 0);
       };
    }

    Ignoring error checking the above is reasonably close.  Be careful with Reader/Writer though as they auto-close the stream when they are disposed. If you don't want that then you either need to create your own Reader/Writer versions (I expose my via extension methods of the Stream class) or create a wrapper stream type that ignores close requests.  The wrapper stream is easier as you just defer all requests to the wrapped stream except disposal so the Reader/Writer is happy but I find extension methods on the Stream class cleaner.

    Michael Taylor - 4/3/2012
    http://msmvps.com/blogs/p3net

    • Marked as answer by brown71576 Tuesday, April 03, 2012 5:27 PM
    Tuesday, April 03, 2012 3:47 PM
  • I'm not sure about your write code.  It seems overly complex.  If you want to write a byte array then you can do something like this:

    private void WriteData ( byte[] data, Stream stream )
    {
        using (var writer = new BinaryWriter(stream))
        {
            //Message header
           ...
          writer.Write(data.Length);  //Write as an Int32
    
          //Data
          writer.Write(data);
       };
    }
    
    private byte[] ReadData ( Stream stream )
    {
       using (var reader = new StreamReader(stream))
       {
          //Message header
          ...
          int length = reader.ReadInt32();
          
          var data = new byte[length];
          int currentPos = 0;
          int remaining = length;
          int read;
          do
          {
              read = reader.Read(data, currentPos, remaining);
              currentPos += read;
              remaining -= read;
          } while (read > 0);
       };
    }

    Ignoring error checking the above is reasonably close.  Be careful with Reader/Writer though as they auto-close the stream when they are disposed. If you don't want that then you either need to create your own Reader/Writer versions (I expose my via extension methods of the Stream class) or create a wrapper stream type that ignores close requests.  The wrapper stream is easier as you just defer all requests to the wrapped stream except disposal so the Reader/Writer is happy but I find extension methods on the Stream class cleaner.

    Michael Taylor - 4/3/2012
    http://msmvps.com/blogs/p3net


    You sample does not seem to handle Asynchronus Callbacks?
    Tuesday, April 03, 2012 4:38 PM
  • I have worked through a solution

            /// <summary>
            /// Callback for the read opertaion.
            /// </summary>
            /// <param name="result">The async result object</param>
            private void ReadCallback(IAsyncResult result)
            {
                Client client = result.AsyncState as Client;
                if (client == null)
                {
                    return;
                }
                
                NetworkStream networkStream = client.NetworkStream;
       
                int BytesReceived = 0;
                int CurrentPosition = 0;
                // This will hold the actual payload. This array will not have the header
                // data that was send by the client
                Byte[] m_ReadBuffer = null;
                // Alaways will be null at this point
                if (m_ReadBuffer == null)
                {
                    // This will hold the number of bytes we need to read 
                    // in order to determine how big the packet is.
                    Byte[] SizeBuffer = new Byte[1];
                    // Get the 1st byte, this will tell us how many bytes to read
                    // in order to k now the size of the payload.
                    //
                    // Example: [4][8][2][0][0][...][n]
                    //
                    // [4] => read the next 4 bytes to get the actual size of the payload.
                    SizeBuffer[0] = client.Buffer[0];
                    // Initialize a new byte arrays that lets us know how big the payload is
                    // [8][2][0][0] => 8200 Bytes is the payload size.
                    Byte[] NewBuffer = new Byte[SizeBuffer[0]];
                    // Used to dim a BYte array for the payload size
                    string Temp = string.Empty;
                    // Get the Payload size
                    for (int i = 0; i < NewBuffer.Length; i++)
                    {
                        NewBuffer[i] = client.Buffer[i + 1];
                        Temp += NewBuffer[i].ToString();
                    }
                    int Size = Convert.ToInt32(Temp);
                    m_ReadBuffer = new Byte[Size];
                    // Store the first packet of data.
                    ReadElements(SizeBuffer.Length + NewBuffer.Length, client.Buffer, ref m_ReadBuffer, ref CurrentPosition);
                    // Total bytes received minus the header data
                    BytesReceived = client.Buffer.Length - (SizeBuffer.Length + NewBuffer.Length);
                }           
                // Now make sure we get all the data sent by the client
                while (BytesReceived != m_ReadBuffer.Length)
                {
                    // Get how many more bytes we need to have all data.
                    int Difference = m_ReadBuffer.Length - CurrentPosition;
                    // If its more than the default packets size, just read the whole packets
                    // else only read the number of bytes needed to get the rest of the data.
                    if (Difference > 8192)
                    {
                        Byte[] b = new Byte[8192];
                        BytesReceived = BytesReceived + networkStream.Read(b, 0, 8192);
                        ReadElements(0, b, ref m_ReadBuffer, ref CurrentPosition);
                    }
                    else
                    {
                        Byte[] b = new Byte[Difference];
                        try
                        {
                            BytesReceived = BytesReceived + networkStream.Read(b, 0, Difference);
                        }
                        catch (Exception Ex)
                        {
                            string Message = Ex.Message;
                        }
                        // Copy bytes to m_ReadBuffer starting at a specific position
                        ReadElements(0, b, ref m_ReadBuffer, ref CurrentPosition);
                    }                
                }
                int read = networkStream.EndRead(result);
                if (read == 0)
                {
                    lock (this.clients)
                    {
                        this.clients.Remove(client);
                        return;
                    }
                }
                //Here is where I will handle the data
                // Start listening for another transfer from the client.
                networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
            }
        }

    • Marked as answer by brown71576 Tuesday, April 03, 2012 5:27 PM
    Tuesday, April 03, 2012 5:26 PM