В настоящее время я пытаюсь настроить сервер, который принимает несколько клиентов и может получать и отвечать на сообщения.
Клиент и сервер используют общую библиотеку, которая содержит класс Request
, которыйсериализуется и отправляется от клиента к серверу и аналогично в обратном порядке.
Сервер асинхронно прослушивает клиентов на каждом из их сокетов и пытается принять полученные данные и десериализовать данные в класс Request
.
Данные отправляются через NetworkStream
, используя BinaryFormatter
для отправки непосредственно в сокет. Затем полученные данные анализируются с помощью Network Stream
на другом конце.
Я пытался использовать MemoryStream
для сохранения данных в буфере, а затем десериализовать их, как показано ниже, однако это нет работал. Непосредственная десериализация NetworkStream
тоже не сработала.
Поиск вокруг Я не нашел много информации, которая бы работала для моего варианта использования.
Это активный код после сокетовуспешно подключено:
По классу запросов, отправка от клиента:
public void SendData(Socket socket)
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new NetworkStream(socket, false);
formatter.Serialize(stream, this);
stream.Close();
}
Код сервера, получающий эти данные:
public void Receive(Socket socket)
{
try
{
ReceiveState state = new ReceiveState(socket);
state.Stream.BeginRead(state.Buffer, 0, ReceiveState.BUFFER_SIZE, new AsyncCallback(DataReceived), state);
}
catch (Exception e)
{
Logger.LogError(e.ToString());
}
}
private void DataReceived(IAsyncResult ar)
{
ReceiveState state = (ReceiveState)ar.AsyncState;
int bytesRead = state.Stream.EndRead(ar);
//Resolve Message
try
{
IFormatter formatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream(state.Buffer, 0, bytesRead);
Request request = (Request)formatter.Deserialize(memoryStream);
Logger.Log("Request Received Successfully");
ResolveRequest(request, state.Socket);
}
catch (Exception e)
{
Logger.LogError(e.ToString());
}
//Resume listening
Receive(state.Socket);
}
public class ReceiveState
{
public byte[] Buffer;
public const int BUFFER_SIZE = 1024;
public Socket Socket;
public NetworkStream Stream;
public ReceiveState(Socket socket)
{
Buffer = new byte[BUFFER_SIZE];
Socket = socket;
Stream = new NetworkStream(Socket, false);
}
}
В настоящее время, когда BeginRead()
вызывается на NetworkStream
Я получаю один байт данных, а затем остальные данные при вызове следующего BeginRead()
.
например. Сериализованные данные должны быть: 00-01-00-00-00-FF-FF-FF-FF-01-...
Ireceive: 00
, за которым следует 01-00-00-00-FF-FF-FF-FF-01-...
, который не удается десериализовать.
Я полагаю, что проблема заключается в том, что метод DataReceived()
вызывается, как только появляются какие-либо данные, то есть взятый единственный байт,затем остаток приходит до возобновления прослушивания.
Есть ли способ убедиться, что каждое сообщение получено полностью перед десериализацией? Я хотел бы иметь возможность десериализовать объект, как только будет получен последний байт.