Проверка завершения отправки SendAsync - PullRequest
2 голосов
/ 21 декабря 2009

Как в приведенном ниже упрощенном коде, проверка того, что 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 ]

2 голосов
/ 21 декабря 2009

Я подозреваю, что вы читаете пример на http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx и видите, что они проверяют длину байта в ProcessReceive.

Это сделано для того, чтобы получить все полученные байты, поскольку вы не можете контролировать, сколько байтов отправляется другой стороной каждый раз.

Когда вы выполняете отправку, это избыточно, так как фреймворк обрабатывает отправку всех ваших данных за вас.

1 голос
/ 15 мая 2011

Я думаю, что-то не так в вашем коде:

// Check that all the data was sent
int offset = e.Offset + e.BytesTransferred;
if (offset < e.Count)
{

e.Count - это количество байтов для передачи, это не смещение в байтовом массиве.

Итак, чтобы сравнить яблоки с яблоками, вы бы сказали:

if (e.BytesTransfered

...