TCP/IP Problem mit WSACancelBlockingCall

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Mono.

    TCP/IP Problem mit WSACancelBlockingCall

    Ich hab ein Problem das sich seit Tagen nicht lösen lässt, ich habe anhan des Multiserver TCP Tutorials einen Client und Server gecodet.
    Alles ging perfekt auch das schließen des Servers, aber nun wo ich alles mit OOP gemacht hab kriege ich beim schließen des Server folgende Exception

    Quellcode

    1. Read: Von der Übertragungsverbindung können keine Daten gelesen werden: Ein Blockierungsvorgang wurde durch einen Aufruf von WSACancelBlockingCall unterbrochen.


    Das "Read" dient nur zum finden des Fehlers.

    Hier mal alles was ich gecodet habe:

    Server:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Net
    2. Imports System.Net.Sockets
    3. Imports System.Threading.Thread
    4. Imports System.IO
    5. Public Class server
    6. Public Event newmsg(ByVal message As String, ByVal c As connection)
    7. Public Event c_connection_lost(ByVal c As connection)
    8. Public Event c_connected(ByVal c As connection)
    9. Public Event server_closed()
    10. Private tcpserver As TcpListener
    11. Private client As New TcpClient
    12. Private ipendpoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 8000)
    13. Private list As New List(Of connection)
    14. Dim t As Threading.Thread = New Threading.Thread(AddressOf waitforconnection)
    15. Private receive As Boolean
    16. Public Sub start(ByVal port As Integer)
    17. Try
    18. close()
    19. client = New TcpClient
    20. ipendpoint = New IPEndPoint(IPAddress.Any, port)
    21. tcpserver = New TcpListener(ipendpoint)
    22. tcpserver.Start()
    23. Catch ex As Exception
    24. MsgBox("Server failed to start; " & ex.Message)
    25. End Try
    26. receive = True
    27. t = New Threading.Thread(AddressOf waitforconnection)
    28. t.IsBackground = True
    29. t.Start()
    30. End Sub
    31. Public Sub close()
    32. Try
    33. receive = False
    34. For Each c As connection In list
    35. c.close()
    36. Next
    37. MsgBox("2")
    38. client.Close()
    39. MsgBox("3")
    40. tcpserver.Stop()
    41. MsgBox("4")
    42. Catch ex As Exception
    43. MsgBox("Serverclose: " & ex.Message)
    44. End Try
    45. RaiseEvent server_closed()
    46. End Sub
    47. Private Sub waitforconnection()
    48. While receive
    49. Try
    50. client = tcpserver.AcceptTcpClient
    51. Catch ex As Exception
    52. Exit Sub
    53. End Try
    54. Dim tmp_stream As NetworkStream = client.GetStream
    55. Dim c As New connection(tmp_stream)
    56. c.lst = New ListViewItem
    57. c.lst.Text = c.read 'Username lesen
    58. c.lst.SubItems.Add(c.read) 'Land lesen
    59. AddHandler c.newmsg, AddressOf newmsg_fromclient
    60. AddHandler c.connected, AddressOf client_connected
    61. AddHandler c.connection_lost, AddressOf client_connection_lost
    62. list.Add(c)
    63. c.start()
    64. End While
    65. End Sub
    66. Private Sub client_connected(ByVal c As connection)
    67. RaiseEvent c_connected(c)
    68. End Sub
    69. Private Sub newmsg_fromclient(ByVal message As String, ByVal c As connection)
    70. RaiseEvent newmsg(message, c)
    71. End Sub
    72. Private Sub client_connection_lost(ByVal c As connection)
    73. list.Remove(c)
    74. RaiseEvent c_connection_lost(c)
    75. End Sub
    76. End Class


    Connection:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Net.Sockets
    3. Public Class connection
    4. Private stream As NetworkStream
    5. Private streamw As StreamWriter
    6. Private streamr As StreamReader
    7. Public receive As Boolean
    8. Public lst As ListViewItem
    9. Public Event newmsg(ByVal message As String, ByVal c As connection)
    10. Public Event connection_lost(ByVal c As connection)
    11. Public Event connected(ByVal c As connection)
    12. Dim t As Threading.Thread = New Threading.Thread(AddressOf listen)
    13. Sub New(ByVal server_stream As NetworkStream)
    14. stream = server_stream
    15. streamr = New StreamReader(stream)
    16. streamw = New StreamWriter(stream)
    17. End Sub
    18. Sub start()
    19. receive = True
    20. Dim t As New Threading.Thread(AddressOf listen)
    21. t.Start()
    22. RaiseEvent connected(Me)
    23. End Sub
    24. Sub close()
    25. receive = False
    26. streamr.Close()
    27. streamw.Close()
    28. stream.Close()
    29. End Sub
    30. Sub write(ByVal s As String)
    31. Try
    32. streamw.WriteLine(s)
    33. streamw.Flush()
    34. Catch ex As Exception
    35. close()
    36. MsgBox("Write: " & ex.Message)
    37. RaiseEvent connection_lost(Me)
    38. End Try
    39. End Sub
    40. Function read()
    41. Try
    42. Return streamr.ReadLine()
    43. Catch ex As Exception
    44. close()
    45. MsgBox("Read: " & ex.Message) 'hier kommt die Exception, denke es liegt daran das er schließen will, aber er liest ja noch im Stream
    46. Return Nothing
    47. RaiseEvent connection_lost(Me)
    48. End Try
    49. End Function
    50. Private Sub listen()
    51. While receive
    52. Try
    53. Dim tmp As String = read()
    54. If Not tmp = Nothing Then
    55. RaiseEvent newmsg(tmp, Me)
    56. End If
    57. Catch ex As Exception
    58. close()
    59. MsgBox("Listen:" & ex.Message)
    60. RaiseEvent connection_lost(Me)
    61. Exit While
    62. End Try
    63. End
    64. End While
    65. End Sub
    66. End Class



    MfG
    Hey,

    das ist echt übelster Code, das sei mal gesagt. Erstens OPTION STRICT ON, VisualBasic-NameSpace raus.

    VB.NET-Quellcode

    1. Public Sub start(ByVal port As Integer)
    2. Try
    3. close()
    4. client = New TcpClient
    5. ipendpoint = New IPEndPoint(IPAddress.Any, port)
    6. tcpserver = New TcpListener(ipendpoint)
    7. tcpserver.Start()
    8. Catch ex As Exception
    9. MsgBox("Server failed to start; " & ex.Message)
    10. End Try
    11. receive = True
    12. t = New Threading.Thread(AddressOf waitforconnection)
    13. t.IsBackground = True
    14. t.Start()
    15. End Sub


    Was soll der Aufruf von Close beim starten des Servers? Weiterhin versuchst Du hier, den Server zu starten. Geht es schief, machst Du trotzdem weiter? Alleine beim Aufruf von start fliegen jede Menge Exceptions. Du kriegst nur nichts davon mit, weil Du Try-Catch wie ein Irrer verwendest, ohne auch nur im Ansatz mit Hilfe dieser Exceptions den Programmfluss sinnvoll zu steuern^^. Zeig mal, wie die Client-Seite aussieht.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Oh, das mit dem "Close()" hatte ich anfangs nur drin um zu gucken ob ich die gleiche Exception bekomme, wenn noch kein Server gestart ist(sorry :/, hab ich vergessen).
    Exit Sub hab ich vergessen, werde ich hinzufügen.

    Client kommt gleich, mich würde intressieren was in deine Augen beim Code "übel" ist, bin immer für Kritik offen :whistling: .

    Edit:// Wo währe es denn deiner Meinung nach sinnvoll die TryCatch blöcke zu entfernen, an mancher stelle brauche ich sie auch um zu erkennen ob der Client disconnected.

    Edit://

    Der Client ist nicht wirklich gut einfach nur die das Beispiel bissl gemoddet.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Net.Sockets
    3. Imports System.Net
    4. Public Class Form1
    5. Private stream As NetworkStream
    6. Private streamw As StreamWriter
    7. Private streamr As StreamReader
    8. Private client As New TcpClient
    9. Private t As New Threading.Thread(AddressOf Listen)
    10. Dim username As String
    11. Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    12. username = InputBox("Input username", "Username", "Unknown")
    13. start()
    14. End Sub
    15. Private Sub start()
    16. Try
    17. client = New TcpClient
    18. client.Connect("127.0.0.1", 5285)
    19. If client.Connected Then
    20. stream = client.GetStream
    21. streamw = New StreamWriter(stream)
    22. streamr = New StreamReader(stream)
    23. writestream(username)
    24. writestream(getc)
    25. t = New Threading.Thread(AddressOf Listen)
    26. t.Start()
    27. Else
    28. Msgbox("Fehler beim starten")
    29. End If
    30. Catch ex As Exception
    31. Msgbox(ex.message)
    32. End Try
    33. End Sub
    34. Private Sub Listen()
    35. While client.Connected
    36. Dim tmp As String = readstream()
    37. msgbox(tmp)
    38. End While
    39. End Sub
    40. Private Sub writestream(ByVal s As String)
    41. streamw.WriteLine(s)
    42. streamw.Flush()
    43. End Sub
    44. Private Function readstream()
    45. Dim s As String = Nothing
    46. s = streamr.ReadLine()
    47. Return s
    48. End Function
    49. Function getc()
    50. Try
    51. Dim httpRequest As HttpWebRequest = HttpWebRequest.Create("http://www.hostip.info/")
    52. Dim httpResponse As HttpWebResponse = httpRequest.GetResponse()
    53. Dim reader As StreamReader = New StreamReader(httpResponse.GetResponseStream)
    54. Dim httpContent As String = reader.ReadToEnd
    55. Dim T As TextBox = New TextBox
    56. T.Text = httpContent
    57. For Each s As String In T.Lines
    58. If s.Contains("Location:") Then
    59. s = s.Replace("Location: <b>", Nothing)
    60. s = s.Replace("</b><br/><br/>", Nothing)
    61. T.Text = s
    62. End If
    63. Next
    64. Return T.Text
    65. Catch ex As Exception
    66. Return ex.Message
    67. End Try
    68. End Function
    69. End Class




    Edit: :P //

    Hab Option Strict ON gefixxt

    MfG

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „schockerjo“ ()

    VB.NET-Quellcode

    1. Private Sub listen()
    2. While receive
    3. Try
    4. Dim tmp As String = read()
    5. If Not tmp = Nothing Then
    6. RaiseEvent newmsg(tmp, Me)
    7. End If
    8. Catch ex As Exception
    9. close()
    10. MsgBox("Listen:" & ex.Message)
    11. RaiseEvent connection_lost(Me)
    12. Exit While
    13. End Try
    14. End '<======= Da ist Dein Problem.
    15. End While
    16. End Sub


    Schau auf das Kommentar, das ich eingefügt habe. Hier beendest Du die Ausführung und es kommt zu diesem Fehler. Das hättest im Grunde selber finden müssen, wenn Du anständig debugged hättest. Zum Rest sag ich evtl. später was.

    VB.NET-Quellcode

    1. Dim T As TextBox = New TextBox
    2. T.Text = httpContent
    3. For Each s As String In T.Lines
    4. If s.Contains("Location:") Then
    5. s = s.Replace("Location: <b>", Nothing)
    6. s = s.Replace("</b><br/><br/>", Nothing)
    7. T.Text = s
    8. End If
    9. Next
    10. Return T.Text


    Was ist das? Ich mein, warum erstellst Du hier eine TextBox? Junge, Junge. :cursing:
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Dann kann ich Dir leider nicht weiter helfen. Ich hab Deinen Code kopiert, bei mir eingefügt. Bei mir kommt keine Exception, nachdem ich "End" entfernt habe.

    Lad mal Dein Projekt, so wie es ist, hoch. Mit Allem drum und dran. Dann schau ich gerne nochmal rein.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Es wird schätze ich am Streamreader des Clients liegen der versucht aus einem geschlossenem Networkstream Daten zu lesen.
    Ich kann dir nur empfehlen dich etwas mit der Materie zu beschäftigen und auch diesen Server/Client Ansatz kann ich absolut nicht empfehlen.

    Das Beispiel dient wohl eher dazu, zu begreifen wie ein Server/Client System grundsätzlich funktioniert. Es ist jedoch absolut unsinnig soviele Thread Objekte zu erstellen für jeden Client.
    Das ist meine Signatur und sie wird wunderbar sein!