Клиентское приложение создает List<Person> data
из ObservableCollection<Person>
, затем преобразует data
в byte[] array
и отправляет Length
из array
на сервер перед отправкой фактического array
таким образом:
void SendData(object o)
{
var data = new List<Person>(ListOfPerson);
var array = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
socket.Send(BitConverter.GetBytes(array.Length));
socket.Send(array);
ListOfPerson.Clear();
}
и сервер сначала считывает длину из e.Buffer
, которая изначально была установлена на 4, затем сбрасывает e.Buffer
и получает все, что клиент отправляет в одном Receive
вызове, подобном этому:
void Receive(object sender, SocketAsyncEventArgs e)
{
int length = BitConverter.ToInt32(e.Buffer, 0);
SetBuffer(e, length);
int read = (sender as Socket).Receive(e.Buffer);
var json = Encoding.UTF8.GetString(e.Buffer);
SetBuffer(e, 4);
(sender as Socket).ReceiveAsync(e);
}
void SetBuffer(SocketAsyncEventArgs e, int length) => e.SetBuffer(new byte[length], 0, length);
Неважно, сколько байтов отправляет клиент, сервер всегда получает все за один Receive
вызов, а read
показывает, что он получил все это! В данном конкретном случае я отправил список из 5 Person
, который принимает имя и возраст
public class Person
{
public string Name { get; set; }
public Nullable<int> Age { get; set; }
public Person(string name, Nullable<int> age)
{
Name = name;
Age = age;
}
public override string ToString() => Name + " " + Age;
}
Я скопировал 9999 слов из генератора Lorem ipsum и вставил его как Name
из всех 5Person
и 10 как Age
. Таким образом, длина отправленного клиента составила 341706 байт, и сервер получил все эти вызовы и преобразовал их в строку json! Буду ли я всегда получать все данные, отправляемые клиентом за один вызов, независимо от количества байтов в TCP-соединении?