Отправка большего сериализованного объекта по сети вызывает сбой в работе
Я боролся с сериализацией объекта по сети для небольшого проекта, над которым я работал. Код, который я использую, работает почти безупречно, иногда байты загружаются некорректно, но это можно исправить, просто перезагрузив интерфейс. Однако при обмене данными в той же системе, но как только вы выходите в другую систему, код работает только частично. Как только я пытаюсь отправить массив строк размером 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 ответ
Хорошо, после некоторого возни, я понял, что мой клиент был мутантом асинхронных и синхронизирующих сокетов. Итак, я понизил их все для синхронизации, и теперь он работает нормально. Колбэки иногда зависали и не переходили на следующий уровень.