Отправка большего сериализованного объекта по сети вызывает сбой в работе

Я боролся с сериализацией объекта по сети для небольшого проекта, над которым я работал. Код, который я использую, работает почти безупречно, иногда байты загружаются некорректно, но это можно исправить, просто перезагрузив интерфейс. Однако при обмене данными в той же системе, но как только вы выходите в другую систему, код работает только частично. Как только я пытаюсь отправить массив строк размером 30 по сети, сервер перестает сообщать о получении пакетов и, как ни странно, ничего не выдает ошибку. Там было несколько ошибок, которые появляются время от времени:

System.InvalidOperationException: Cannot block a call on this socket while an earlier asynchronous call is in progress.
   at System.Net.Sockets.Socket.ValidateBlockingMode()
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, SocketError& errorCode)
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.Socket.Receive(Byte[] buffer)
   at DMAssist.AsynchronousClient.Receive(Socket client) in C:\Users\crud4\documents\visual studio 2015\Projects\DMAssist\DMAssist\asyncsclient.cs:line 160
   at DMAssist.AsynchronousClient.StartClient(Object obj, Boolean expectresponse) in C:\Users\crud4\documents\visual studio 2015\Projects\DMAssist\DMAssist\asyncsclient.cs:line 119

Это основная ошибка, которую я постоянно получаю в консоли, и я не знаю, как с ней бороться. Я не очень опытен в сетевом программировании, поэтому мне не хватает головы, чтобы понять, где я ошибся.

Моя основная проблема заключается в том, что по какой-то причине сервер перестает сообщать о принимаемых байтах, когда клиент пытается отправить более 330 байтов, и вызывает общее затруднение. Сервер определенно показывает получение соединения, но по какой-то причине простой сразу убивает его. Если кто-нибудь знает, что происходит или как это исправить, я был бы очень признателен за помощь!

Заранее спасибо!

Клиент:

private netObject Receive(Socket client)
        {
            byte[] buffer = new byte[1024];
            int iRx = client.Receive(buffer);

            object rawbytes = ByteArrayToObject(buffer);
            netObject recvobject = (netObject)rawbytes;

            receiveDone.Set();

            return recvobject;
        }

public netObject StartClient(Object obj, bool expectresponse)
        {
            // Connect to a remote device.
            try
            {
                // Establish the remote endpoint for the socket.
                // The name of the 
                // remote device is "host.contoso.com".
                IPAddress ipAddress = IPAddress.Parse(ip);
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, 25599);

                // Create a TCP/IP socket.
                Socket client = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);

                // Connect to the remote endpoint.
                client.BeginConnect(remoteEP,
                    new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();

                // Send test data to the remote device.
                Send(client, ObjectToByteArray(obj));
                sendDone.WaitOne();

                Send(client, Encoding.ASCII.GetBytes("<EOF>"));
                sendDone.WaitOne();


                // Receive the response from the remote device.
                if (expectresponse)
                {
                    netObject serverdata = Receive(client);
                    receiveDone.WaitOne();
                    return serverdata;
                }

                // Release the socket.
                client.Shutdown(SocketShutdown.Both);
                client.Close();

                return new netObject();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return new netObject();
            }
        }

private static void Send(Socket client, byte[] data)
        {

            byte[] byteData = data;

            // Begin sending the data to the remote device.
            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }

Сервер:

public void ReadCallback(IAsyncResult ar)
        {
            try {
                String content = String.Empty;

                // Retrieve the state object and the handler socket
                // from the asynchronous state object.
                StateObject state = (StateObject)ar.AsyncState;
                Socket handler = state.workSocket;

                // Read data from the client socket. 
                int bytesRead = handler.EndReceive(ar);

                Console.WriteLine(bytesRead);

                if (bytesRead > 0)
                {
                    if (bytesRead != 5)
                    {
                        Array.Copy(state.buffer, state.cleanbuffer, bytesRead);
                    }

                    // There  might be more data, so store the data received so far.
                    state.sb.Append(Encoding.ASCII.GetString(
                        state.buffer, 0, bytesRead));

                    // Check for end-of-file tag. If it is not there, read 
                    // more data.
                    content = state.sb.ToString();

                    Console.WriteLine("SERVER: Recieved " + bytesRead + " bytes");

                    if (content.IndexOf("<EOF>") > -1)
                    {
                        // All the data has been read from the 
                        // client. Display it on the console.


                        /*Console.WriteLine("Read {0} bytes from socket. Data : {1}",
                            content.Length, content);*/

                        object rawbytes = ByteArrayToObject(state.cleanbuffer);
                        netObject recvobject = (netObject)rawbytes;
                       }

                        // Echo the data back to the client.
                        Send(handler, ObjectToByteArray((object)recvobject));

                    }
                    else {
                        // Not all data received. Get more.
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReadCallback), state);
                    }
                }
            } catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }
        }

 private void Send(Socket handler, byte[] data)
        {
            // Convert the string data to byte data using ASCII encoding.
            byte[] byteData = data;

            // Begin sending the data to the remote device.
            handler.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), handler);
        }

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket handler = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.
                int bytesSent = handler.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to client.", bytesSent);

                handler.Shutdown(SocketShutdown.Both);
                handler.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

1 ответ

Хорошо, после некоторого возни, я понял, что мой клиент был мутантом асинхронных и синхронизирующих сокетов. Итак, я понизил их все для синхронизации, и теперь он работает нормально. Колбэки иногда зависали и не переходили на следующий уровень.

Другие вопросы по тегам