Проверка завершения отправки SendAsync
Как и в приведенном ниже упрощенном коде, проверка того, что SendAsync() завершил передачу всех намеченных байтов в буфере, является правильным решением? Или это избыточно? Это для сокета соединения TCP. Я особенно обеспокоен необходимостью выполнить второй дополнительный вызов SendAsync() внутри ProcessSend().
Например, если бы у меня было несколько потоков, передающих данные клиенту, используя новый (объединенный в пул) SocketAsyncEventArg для каждого сообщения, разве не возможно, что одновременная отправка могла бы прерваться между частично переданными сообщениями? Или это хорошая причина для контролируемого доступа к клиенту, позволяя использовать только один SocketAsyncEventArg для отправки данных?
private void ProcessSend(SocketAsyncEventArgs e)
{
// Check that data was sent
if ((e.SocketError == SocketError.Success) && (e.BytesTransferred > 0))
{
AsyncSendUserToken token = (AsyncSendUserToken)e.UserToken;
// Check that all the data was sent
int offset = e.Offset + e.BytesTransferred;
if (offset < e.Count)
{
// Call send again to finish the send
e.SetBuffer(offset, e.Count - offset);
bool _willRaiseEvent = token.Socket.SendAsync(e);
if (!_willRaiseEvent)
ProcessSend(e);
}
}
}
2 ответа
Я подозреваю, что вы читаете пример по адресу http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx и видите, что они проверяют длину байта в ProcessReceive.
Это сделано для того, чтобы получить все полученные байты, так как вы не можете контролировать, сколько байтов отправляется другой стороной каждый раз.
Когда вы выполняете отправку, это избыточно, так как инфраструктура обрабатывает отправку всех ваших данных за вас.
Я думаю, что-то не так в вашем коде:
// Check that all the data was sent
int offset = e.Offset + e.BytesTransferred;
if (offset < e.Count)
{
e.Count - это количество байтов для передачи, это не смещение в байтовом массиве.
Итак, чтобы сравнить яблоки с яблоками, вы бы сказали:
if (e.BytesTransfered