none
IO Exception im TcpClient RRS feed

  • Frage

  • Hallo und guten Abend,

    mein TcpClient wirft bei grossen Mails (über 2 MB) eine Exception:

    System.IO.IOException: Von der Übertragungsverbindung können keine Daten gelesen werden: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat. ---> System.Net.Sockets.SocketException: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
       bei System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
       bei System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
       --- Ende der internen Ausnahmestapelüberwachung ---
       bei System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
       bei KvSafenet.CConnection.WaitforAnswer(TcpClient tcpClient, String& strRet) in D:\VBEntwicklung\ML5.1.0.1\KvSafenet\CConnection.vb:Zeile 254.

    Kleinere Mails werden problemlos verarbeitet. Komisch ist, dass der Fehler beim schrittweisen Durchgehen der Funktion WaitforAnswer (s.u.) nicht auftritt. Hab schon den Buffer von 1024 auf 2048 erhöht (immer noch zu wenig?) und ein Sleep eingebaut. Alles hilft nicht.

    Der Aufruf kommt von

                    If InlineAssignHelper(strErr, SendText(tcpClient, "RETR " & number & Environment.NewLine)).Length > 0 Then
                        'Continue For
                    Else                                                                                    'Daten sind in einer Mail
                        InlineAssignHelper(strErr, WaitforAnswer(tcpClient, strRet))
                        listRet.Add(strRet)
                    End If

    Und hier die zwei beteiligten Funktionen:

        Private Function WaitforAnswer(tcpClient As TcpClient, ByRef strRet As String) As String
            'der Verbindungssocket
            Dim iRead As Integer
            Dim buf As Byte() = New Byte(2047) {}
            Dim bufRet As Byte() = New Byte(-1) {}
            Dim bufTemp As Byte()
            Dim strErr As String = ""
    
            strRet = ""
            Try
                Thread.Sleep(1000)
                While True
                    If InlineAssignHelper(iRead, tcpClient.GetStream().Read(buf, 0, buf.Length)) <> 0 Then
                        bufTemp = New Byte(bufRet.Length + (iRead - 1)) {}
                        bufRet.CopyTo(bufTemp, 0)
                        For idx As Integer = 0 To iRead - 1
                            bufTemp(bufRet.Length + idx) = buf(idx)
                        Next
                        bufRet = bufTemp
                    End If
                    If iRead < 2048 Then
                        strRet = System.Text.Encoding.UTF8.GetString(bufRet)
                        Return ""
                    End If
                End While
            Catch exc As Exception
                strErr = exc.ToString()
            End Try
            Return strErr
        End Function
    
        Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
            target = value
            Return value
        End Function

    Wäre toll, wenn jemand von euch herausfindet, woran das liegt.

    Viele Grüße Norbert


    Montag, 27. Januar 2020 16:10

Alle Antworten

  • Es scheint ein Timing Problem zu sein. Hab folgende Schleife eingebaut:

                    While Not tcpClient.GetStream.DataAvailable
                        Thread.Sleep(200)
                    End While
    
                    If InlineAssignHelper(iRead, tcpClient.GetStream().Read(buf, 0, buf.Length)) <> 0 Then

    Es werden 7 Mails abgeholt, wovon 2 über 3 MB gross sind. Hab mich hochgehangelt von 20 ms bis 200 ms. Sah zwischendurch sehr erfolgsversprechend aus. Bei 50 ms kam immerhin 1 grosse durch. Zwei habe ich mit dieser Methode nicht geschafft. Bei 200 ms war gar kein Erfolg mehr zu verzeichnen.

    Hat noch jemand eine Idee?

    Montag, 27. Januar 2020 17:44