3 Stimmen

Prüfen, ob SendAsync das Senden beendet hat

Ist es richtig, wie im unten stehenden vereinfachten Code zu prüfen, ob SendAsync() die Übertragung aller vorgesehenen Bytes im Puffer abgeschlossen hat? Oder ist das überflüssig? Dies ist für einen TCP-Verbindungssocket. Ich bin besonders besorgt darüber, einen zweiten Unteraufruf von SendAsync() innerhalb von ProcessSend() ausführen zu müssen.

Wenn ich z. B. mehrere Threads habe, die Daten an einen Client übertragen und dabei für jede Nachricht ein neues (gepooltes) SocketAsyncEventArg verwenden, ist es dann nicht möglich, dass sich ein gleichzeitiges Senden zwischen eine teilweise übertragene Nachricht schiebt? Oder ist dies ein guter Grund für einen kontrollierten Zugriff auf den Client, indem nur ein SocketAsyncEventArg für die Datenübertragung verwendet werden darf?

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);
        }
    }
}

0 Stimmen

Ich habe auch gesehen, dass dies passiert, und ich habe auch Fälle gesehen, in denen die Anzahl der übertragenen Bytes größer war als e.Count - e.Offset. Ich habe das eine SocketAsyncEventArgs für das Senden wiederverwendet und eine Methode aufgerufen, die den Puffer füllt und SendAsync von ProcessSend aufruft. Ich fügte Code hinzu, um die aktuelle SocketAsynEventArgs in ProcessSend zu entsorgen und eine neue zu erstellen, und dies hat diesen Fehler gestoppt.

2voto

Mikael Svenson Punkte 37911

Ich vermute, Sie lesen das Beispiel unter http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx und sehen, dass sie die Bytelänge bei ProcessReceive überprüfen.

Dies geschieht, um alle empfangenen Bytes zu erhalten, da Sie keine Kontrolle darüber haben, wie viele Bytes jedes Mal von der anderen Partei gesendet werden.

Wenn Sie einen Sendevorgang durchführen, ist dies überflüssig, da der Rahmen das Senden aller Daten für Sie übernimmt.

1voto

Victor M. Punkte 954

Ich glaube, in Ihrem Code ist etwas falsch:

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

e.Count ist die Anzahl der zu übertragenden Bytes, nicht ein Offset im Byte-Array.

Um also Äpfel mit Äpfeln zu vergleichen, müsste man sagen: "Das ist nicht der Fall:

if (e.BytesTransfered < e.Count) { }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X