Hello, i've a server and client code in which the error i'm getting is: on deserialization-
but when i checked the byte[] length after serialization that i send they are 1550, and then over the tcpclient when i received the byte[] it was 1448 in length...
any help or suggestion would be appreciated

**CLIENT CODE**

static void Main()
        {
            Application.Run(new Form2connectclient2library());
        }

        public void cmdConnect_Click(object sender, System.EventArgs e)
        {
            try
            {
               //****************************TCP NETWORK STREAM*******

                port = Convert.ToInt32(txtPort.Text);
                ip = txtIPAddress.Text;
                myclient = new TcpClient(ip, port);

                recByte = new byte[myclient.ReceiveBufferSize];
                AsyncCallback GetMsgCallback = new AsyncCallback(GetMsg);
                (myclient.GetStream()).BeginRead(recByte, 0, myclient.ReceiveBufferSize, GetMsgCallback, null);



                //*****************************************************

            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
        }

        NetworkStream n;
        public void GetMsg(IAsyncResult ar)
        {
            int byteCount;
            try
            {
                lock (myclient.GetStream())
                {
                    n = (NetworkStream)ar.AsyncState;
                    //Get the number of Bytes received
                    byteCount = (myclient.GetStream()).EndRead(ar);
                }

                    if (byteCount > 1)
                    {

                        MessageBox.Show(byteCount.ToString());
                        M7_1.MessageWrapper_Download msg = (M7_1.MessageWrapper_Download)M7_1.class_ser_deser.DeSerializer(recByte, recByte.Length);



                        if (msg.getType() == M7_1.MessageWrapper_Download.MESSAGETYPE.GET_GROUPS)
                        {
                            DataSet ds_g = (DataSet)msg.msgdata();
                            obj.set_groups_list(ds_g);
                        }


                        if (msg.getType() == M7_1.MessageWrapper_Download.MESSAGETYPE.GET_DOCUMENTS)
                        {
                            DataSet ds_r = (DataSet)msg.msgdata();
                            obj.set_Resource_List(ds_r);
                        }


                        if (msg.getType() == M7_1.MessageWrapper_Download.MESSAGETYPE.FILE)
                        {
                            D_dataTransferObjs obj_file = (D_dataTransferObjs)msg.msgdata();
                            obj.createFile(obj_file);

                        }


                    }
            

                    obj.send_client_obj(myclient);

                    recByte = new byte[myclient.ReceiveBufferSize];//Start a new asynchronous read into readBuffer.
                    AsyncCallback GetMsgCallback = new AsyncCallback(GetMsg);
                    (myclient.GetStream()).BeginRead(recByte, 0, myclient.ReceiveBufferSize, GetMsgCallback, this);
                }
            

            catch (Exception ed)
            {
                myclient.Close();

                MessageBox.Show("Client Disconnected  ");
                MessageBox.Show(ed.ToString());
            }
        }

HERE IS THE DESERIALIZATION CODE...

public static object DeSerializer(byte[] theByteArray, int length)
        {

            MemoryStream ms = new MemoryStream(theByteArray, 0, length);

            ms.Flush();
            ms.Position = 0;
            IFormatter bf = new BinaryFormatter();

            object obj;
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            obj = bf.Deserialize(ms);
            AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            ms.Close();
            return obj;
        }

        public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            try
            {

                AssemblyName an = AssemblyName.GetAssemblyName(@"M7_1.dll");
                Assembly assembly = System.Reflection.Assembly.Load(an);
                if (assembly != null)
                    return assembly;
            }
            catch { ;}

            return Assembly.GetExecutingAssembly();
        }

this is the server code part...

//*****************************TCP NETWRK STREAM *****

                serverThread = new Thread(new ThreadStart(startListen));
                serverThread.Start();

                //****************************************************




            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
            catch (ObjectDisposedException)
            {
                System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket now closed\n");
            }

        }


        public void startListen()
        {
            try
            {
                //Start the tcpListner
                int port = Convert.ToInt32(txtPortNo.Text);
                serverListener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
                serverListener.Start();

                do
                {
                    ReqClient newClient = new ReqClient(serverListener.AcceptTcpClient());
                    newClient.Connect();

                    //*****send Group List****
                    DataSet gds = db.Send_user_Groups_List();
                    M7_1.MessageWrapper_Download msgg = new M7_1.MessageWrapper_Download();
                    msgg.setType(M7_1.MessageWrapper_Download.MESSAGETYPE.GET_GROUPS);
                    msgg.msgdata(gds);
                    newClient.sendList(msgg);

                   

                    //****Send Resource List***
                    DataSet rds = db.Send4Request_Resource_List();
                    M7_1.MessageWrapper_Download msgr = new M7_1.MessageWrapper_Download();
                    msgr.setType(M7_1.MessageWrapper_Download.MESSAGETYPE.GET_DOCUMENTS);
                    msgr.msgdata(rds);
                    newClient.sendList(msgr);

...................


       public class ReqClient
        {
            TcpClient myClient;
            byte[] recByte;

            public ReqClient(TcpClient cl)
            {
                myClient = cl;
            }
            public void Connect()
            {


                recByte = new byte[myClient.ReceiveBufferSize];
                AsyncCallback GetStreamMsgCallback = new AsyncCallback(GetStreamMsg);
                myClient.GetStream().BeginRead(recByte, 0, myClient.ReceiveBufferSize, GetStreamMsgCallback, null);
            }
            public void sendList(M7_1.MessageWrapper_Download Message)
            {

                NetworkStream ns = (myClient).GetStream();
                byte[] arr = M7_1.class_ser_deser.Serializer(Message);
                ns.Write(arr, 0, arr.Length);
                MessageBox.Show(arr.Length.ToString());
                ns.Flush();
               ns.Close();


            }


            public string file_name;
            public void GetStreamMsg(IAsyncResult ar)// used when server waiting for filename from client
            {
                int intCount = 0;
                try
                {
                    //Lock the Client Stream
                    lock (myClient.GetStream())
                    {
                        //Receive the Bytes
                        intCount = myClient.GetStream().EndRead(ar);

                    }

                    if (intCount > 0)
                    {
                        M7_1.MessageWrapper_Download msg = (M7_1.MessageWrapper_Download)M7_1.class_ser_deser.DeSerializer(recByte, recByte.Length);

                        if (msg.getType() == M7_1.MessageWrapper_Download.MESSAGETYPE.REQUESTED_FILE_NAME)
                        {
                           string f_name= (string)msg.msgdata();
                           file_name=f_name;
                           //AccessDatabase4Req a = new AccessDatabase4Req();
                           // a.fetch_file(f_name);
                        }
                        // to do process Message
                    }
                    else
                    {
                        lock (myClient.GetStream())  //check it
                        {
                            recByte = new byte[myClient.ReceiveBufferSize];
                            AsyncCallback GetStreamMsgCallback = new AsyncCallback(GetStreamMsg);
                            myClient.GetStream().BeginRead(recByte, 0, myClient.ReceiveBufferSize, GetStreamMsgCallback, null);
                        }
                    }
                }

                catch (Exception ex)
                {

                }

            }

i have used the available message_wrapper class,
i've spent days on this problem, and i'm unable to figure out what is causing the problem...
why is the msg size different at write() method, and at the client side, why is it smaller in size at line
byteCount = (myclient.GetStream()).EndRead(ar);????

Line 44 in your first post -- Shouldn't that be > 0 ? Upload a sample project and i'll take a look at it.

Edited 6 Years Ago by sknake: n/a

thank you sknake.. i got it..the #
#
n = (NetworkStream)ar.AsyncState; shouldn't be there.. and yes must be >0...
overlooked it!! :S :)

o no, the data received is always fixed size 1480, and is lesser than the data i'm sending from the server..?? whereas i've initialized the bigin receive to be 8192 in byte size.... :(

>>o no, the data received is always fixed size 1480, and is lesser than the data i'm sending from the server

Upload a sample project.

You have something called MTU, MRU, and MSS when dealing with network connections. MTU is typically 1500 or less. Larger values are referred to as jumbo frames. You cant rely on any single packet sending the exact buffer size you want. You can enabled the TCP Dont Fragment bit, but, when your packet touches a router that has an MTU of 1500 you will receive an ICMP fragmentation needed packet back. At that point you have to fragment the packet and resend it... essentially putting you back at square one.

Bottom line is you just need to send the data and reassemble it on the other end. Keep reading the bytes in chunks of N bytes. when the desired buffered size has been buffered in memory then process the data. If not keep reading from the socket until you hit the desired size, or the connection dies....

[edit]
>>o no, the data received is always fixed size 1480,
The IP header takes up 20 bytes of space. So the packet you're receiving has is over a connection with a 1500 MTU, subtract 20 bytes for header, and you get 1480. This is expected.
[/edit]

Edited 6 Years Ago by sknake: n/a

on client connect it is

(myclient.GetStream()).BeginRead(recByte, 0, myclient.ReceiveBufferSize,GetMsg, null);

in the GetMsg(async)
it is

int bytes = (myclient.GetStream()).EndRead(ar);
                if (bytes > 0)
                {
                    count += bytes;
                    sb.Append(Encoding.ASCII.GetString(recByte, 0, bytes));
                 
                    (myclient.GetStream()).BeginRead(recByte, 0, recByte.Length, GetMsg, null);
                }


  Array.Resize(ref recByte, count);

                //****************

                if (count > 0)
                { MessageBox.Show(count.ToString());
                    M7_1.MessageWrapper_Download msg = (M7_1.MessageWrapper_Download)M7_1.class_ser_deser.DeSerializer(recByte, count-1);

... where deserialization takes the length of the array as

public static object DeSerializer(byte[] theByteArray,int length)
            {
                
                MemoryStream ms = new MemoryStream(theByteArray,0,length);
                
                ms.Flush();
                ms.Position=0;
             IFormatter bf = new BinaryFormatter();
              
                object obj;
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
                obj = bf.Deserialize(ms);
                AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
                ms.Close();
                return obj;
            }

but i'm gettign the exception
the stream is not ...valid bf..
the starting contents are...57-34 etc...

Nice example, however, nowadays, there is no need to really re-invent the wheel, you can use .Net Protocol Builder to generate the code for your packets listener and client/server connections ... this tool can generate thousands of lines and packets in seconds ... with threaded listener and non-blocking modes .... see www.protocol-builder.com

This article has been dead for over six months. Start a new discussion instead.