Извините, если раньше об этом спрашивали, но мне трудно искать:
Если я использую BeginSend()
на сокете .NET , какое поведение я должен ожидать в коде, подобном этому (псевдо) коду:
Основной программный код:
Network.OutBound.SendData(messageOne);
Network.OutBound.SendData(messageTwo);
Network.OutBound класс
public void SendData(byte[] buffer)
{
connectedSocket.BeginSend(buffer,0,buffer.Length,SocketFlags.None,SendCompleteMethod);
}
private void SendComplete(arResult)
{
int bytesSent;
bytesSent = arResult.EndSend();
if(bytesSent < arResult.state.buffer.Length)
{
//Not all data sent yet, recall BeginSend
connectedSocket.BeginSend(buffer,bytesSent,buffer.Length - bytesSent,SocketFlags.None,SendCompleteMethod);
}
else
{
//All data sent successfully
}
}
Поскольку я использую BeginSend()
, когда вызывается первый SendData(messageOne)
, он сразу же возвращается и вызывается второй SendData(messageTwo)
.
Однако рассмотрим случай, когда большой объем данных отправляется как для первого, так и для второго сообщения, и отправка завершается с частичным объемом данных, и поэтому BeginSend()
вызывается для отправки оставшихся данных.
Не приведет ли это к смешиванию байтов двух сообщений в исходящем сокете?
Они оба будут работать в отдельных потоках пула потоков и будут отправлять данные в один и тот же сокет. Я понимаю, что сокеты TCP гарантируют, что данные поступают по порядку, но как уровень среды выполнения / сокета узнает, является ли моя BeginSend()
попытка завершить отправку messageOne или начало messageTwo? Насколько это возможно, не будут ли данные отправляться и приниматься на удаленном конце в том же порядке, в котором они были записаны в сокет (даже если именно здесь, кажется, существует вероятность смешения)
Если это так, то какой смысл начинать / заканчивать отправку, если мне нужно сериализовать доступ к нему?
Если у меня есть какой-то флаг, который поднимается, когда messageOne полностью отправлено (даже если потребовалось несколько BeginSend()
попыток отправить все данные), чтобы основной код программы мог дождаться его завершения, прежде чем пытаться отправить другое сообщение?
Должен ли я написать какую-нибудь оболочку исходящей очереди? Или я что-то упустил?