Empfang mit Socket

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von tommy.

    Empfang mit Socket

    Hallo Leute!
    Ich hoffe das ich im richtigen Forum bin.
    Mein Problem liegt beim Socket Empfang
    wenn ich von Server zum Client eine Datei sende empfängt Client zwischen 2 und 7 mal dieselbe vollständige Datei Daten
    wenn ich von Client zum Server eine Datei sende, empfängt Server nur 1 mal die vollständige Datei Daten was auch Richtig ist.
    Kann mir vielleicht ein Helfen?
    Der Code
    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Region " Events "
    2. Public Event Connected(ByVal sender As Winsock)
    3. Public Event Disconnected(ByVal sender As Winsock)
    4. Public Event DataArrival(ByVal sender As Winsock, ByVal BytesTotal As Integer)
    5. Public Event ConnectionRequest(ByVal sender As Winsock, ByVal requestID As Socket)
    6. Public Event SendComplete(ByVal sender As Winsock)
    7. Public Event HandleError(ByVal sender As Winsock, ByVal Description As String, ByVal Method As String, ByVal myEx As String)
    8. Public Event StateChanged(ByVal sender As Winsock, ByVal state As WinsockStates)
    9. #End Region
    10. #Region " Variables "
    11. Private _RemoteIP As String = "127.0.0.1"
    12. Private _LocalPort As Integer = 80
    13. Private _RemotePort As Integer = 80
    14. Private _State As WinsockStates = WinsockStates.Closed
    15. Private _sBuffer As String
    16. Private _buffer() As Byte
    17. Private _byteBuffer(1024) As Byte
    18. Private _sockList As Socket
    19. Private _Client As Socket
    20. #End Region
    21. #Region " Constructors "
    22. Public Sub New()
    23. Me.New(80)
    24. End Sub
    25. Public Sub New(ByVal Port As Long)
    26. Me.New("127.0.0.1", Port)
    27. End Sub
    28. Public Sub New(ByVal IP As String)
    29. Me.New(IP, 80)
    30. End Sub
    31. Public Sub New(ByVal IP As String, ByVal Port As Long)
    32. RemoteIP = IP
    33. RemotePort = Port
    34. LocalPort = Port
    35. End Sub
    36. #End Region
    37. #Region " Properties "
    38. Public Property LocalPort() As Integer
    39. Get
    40. Return _LocalPort
    41. End Get
    42. Set(ByVal Value As Integer)
    43. If GetState = WinsockStates.Closed Then
    44. _LocalPort = Value
    45. Else
    46. Throw New Exception("Must be idle to change the local port")
    47. End If
    48. End Set
    49. End Property
    50. Public Property RemotePort() As Integer
    51. Get
    52. Return _RemotePort
    53. End Get
    54. Set(ByVal Value As Integer)
    55. If GetState <> WinsockStates.Connected Then
    56. _RemotePort = Value
    57. Else
    58. Throw New Exception("Can't be connected to a server and change the remote port.")
    59. End If
    60. End Set
    61. End Property
    62. Public Property RemoteIP() As String
    63. Get
    64. Return _RemoteIP
    65. End Get
    66. Set(ByVal Value As String)
    67. If GetState = WinsockStates.Closed Then
    68. _RemoteIP = Value
    69. Else
    70. Throw New Exception("Must be closed to set the remote ip.")
    71. End If
    72. End Set
    73. End Property
    74. <Browsable(False)> Public ReadOnly Property GetState() As WinsockStates
    75. Get
    76. Return _State
    77. End Get
    78. End Property
    79. #End Region
    80. #Region " Methods "
    81. Public Sub Listen()
    82. Dim x As New System.Threading.Thread(AddressOf DoListen)
    83. x.Start()
    84. End Sub
    85. Public Sub Close()
    86. Try
    87. Select Case GetState
    88. Case WinsockStates.Listening
    89. ChangeState(WinsockStates.Closing)
    90. _sockList.Close()
    91. Case WinsockStates.Connected, WinsockStates.Connecting, WinsockStates.ConnectionPending, WinsockStates.HostResolved, WinsockStates.Open, WinsockStates.ResolvingHost
    92. ChangeState(WinsockStates.Closing)
    93. _Client.Close()
    94. Case WinsockStates.Closed
    95. 'do nothing
    96. End Select
    97. ChangeState(WinsockStates.Closed)
    98. Catch ex As Exception
    99. ChangeState(WinsockStates.Error)
    100. RaiseEvent HandleError(Me, ex.Message, ex.TargetSite.Name, ex.ToString)
    101. End Try
    102. End Sub
    103. Public Sub Accept(ByVal requestID As Socket)
    104. Try
    105. ChangeState(WinsockStates.ConnectionPending)
    106. _Client = requestID
    107. RaiseEvent Connected(Me)
    108. ChangeState(WinsockStates.Connected)
    109. _Client.BeginReceive(_byteBuffer, 0, 1024, SocketFlags.None, AddressOf DoStreamReceive, Nothing)
    110. Catch ex As Exception
    111. ChangeState(WinsockStates.Error)
    112. RaiseEvent HandleError(Me, ex.Message, ex.TargetSite.Name, ex.ToString)
    113. End Try
    114. End Sub
    115. Public Sub Connect()
    116. If GetState = WinsockStates.Connected Or GetState = WinsockStates.Listening Then
    117. RaiseEvent HandleError(Me, "Already open, must be closed first", "Connect", "Nothing here")
    118. Exit Sub
    119. End If
    120. Try
    121. Dim remIP As String
    122. ChangeState(WinsockStates.ResolvingHost)
    123. Try
    124. Dim x As System.Net.IPAddress
    125. x = IPAddress.Parse(_RemoteIP)
    126. remIP = x.ToString
    127. Catch ex1 As Exception
    128. 'not a valid IP address - resolve DNS
    129. Try
    130. Dim x As System.Net.Dns
    131. Dim ip As IPHostEntry = x.GetHostByName(_RemoteIP)
    132. Dim t() As IPAddress = ip.AddressList
    133. remIP = t(0).ToString
    134. Catch ex2 As Exception
    135. ChangeState(WinsockStates.Error)
    136. RaiseEvent HandleError(Me, ex2.Message, ex2.TargetSite.Name, ex2.ToString)
    137. End Try
    138. End Try
    139. ChangeState(WinsockStates.HostResolved)
    140. _Client = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    141. Dim rEP As New IPEndPoint(IPAddress.Parse(remIP), RemotePort)
    142. ChangeState(WinsockStates.Connecting)
    143. _Client.BeginConnect(rEP, New AsyncCallback(AddressOf OnConnected), Nothing)
    144. Catch ex As Exception
    145. ChangeState(WinsockStates.Error)
    146. RaiseEvent HandleError(Me, ex.Message, ex.TargetSite.Name, ex.ToString)
    147. End Try
    148. End Sub
    149. Public Sub Connect(ByVal IP As String, ByVal Port As Integer)
    150. RemoteIP = IP
    151. RemotePort = Port
    152. Connect()
    153. End Sub
    154. #End Region
    155. #Region " Public Functions/Subs "
    156. Public Function LocalIP() As String
    157. Dim h As System.Net.IPHostEntry = System.Net.Dns.GetHostByName(System.Net.Dns.GetHostName)
    158. Return CType(h.AddressList.GetValue(0), Net.IPAddress).ToString
    159. End Function
    160. Public Function RemoteHostIP() As String
    161. Dim iEP As IPEndPoint = _Client.RemoteEndPoint
    162. Return iEP.Address.ToString
    163. End Function
    164. #End Region
    165. #Region " Send Overloads "
    166. Public Sub Send(ByVal Data As String)
    167. Dim sendBytes() As Byte = System.Text.Encoding.ASCII.GetBytes(Data)
    168. Me.Send(sendBytes)
    169. End Sub
    170. Public Sub Send(ByVal Data() As Byte)
    171. Select Case GetState
    172. Case WinsockStates.Closed
    173. 'can't send - not connected
    174. Case WinsockStates.Listening
    175. 'listening
    176. Case WinsockStates.Connected
    177. Try
    178. 'send the bytes that are passed
    179. ReDim Preserve Data(UBound(Data) + 1)
    180. Data(UBound(Data)) = 4
    181. _Client.Send(Data)
    182. Catch ex As Exception
    183. Me.Close()
    184. ChangeState(WinsockStates.Error)
    185. RaiseEvent HandleError(Me, ex.Message, ex.TargetSite.Name, ex.ToString)
    186. End Try
    187. End Select
    188. End Sub
    189. Public Sub Send(ByVal Data As Bitmap)
    190. Dim str As New System.IO.MemoryStream
    191. Data.Save(str, System.Drawing.Imaging.ImageFormat.Bmp)
    192. Dim sendBytes(str.Length - 1) As Byte
    193. str.Position = 0
    194. str.Read(sendBytes, 0, str.Length)
    195. Me.Send(sendBytes)
    196. End Sub
    197. #End Region
    198. #Region " GetData Overloads "
    199. Public Sub GetData(ByRef data As String)
    200. Dim byt() As Byte = Nothing
    201. GetData(byt)
    202. For i As Integer = 0 To UBound(byt)
    203. If byt(i) = 10 Then
    204. data &= vbLf
    205. Else
    206. data &= ChrW(byt(i))
    207. End If
    208. Next
    209. End Sub
    210. Public Sub GetData(ByRef bytes() As Byte)
    211. ReDim bytes(UBound(_buffer))
    212. _buffer.CopyTo(bytes, 0)
    213. Erase _buffer
    214. End Sub
    215. Public Sub GetData(ByRef bitmap As Bitmap)
    216. Dim byt() As Byte = Nothing
    217. GetData(byt)
    218. Dim str As New System.IO.MemoryStream(byt, False)
    219. bitmap = Bitmap.FromStream(str)
    220. End Sub
    221. #End Region
    222. #Region " Private Functions/Subs "
    223. Private Sub ChangeState(ByVal new_state As WinsockStates)
    224. _State = new_state
    225. RaiseEvent StateChanged(Me, _State)
    226. End Sub
    227. Private Sub OnConnected(ByVal asyn As IAsyncResult)
    228. Try
    229. _Client.EndConnect(asyn)
    230. ChangeState(WinsockStates.Connected)
    231. _Client.BeginReceive(_byteBuffer, 0, 1024, SocketFlags.None, AddressOf DoStreamReceive, Nothing)
    232. RaiseEvent Connected(Me)
    233. Catch ex As Exception
    234. ChangeState(WinsockStates.Error)
    235. RaiseEvent HandleError(Me, ex.Message, ex.TargetSite.Name, ex.ToString)
    236. End Try
    237. End Sub
    238. Private Sub DoListen()
    239. Try
    240. Dim tmpSocket As Socket
    241. _sockList = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    242. Dim ipLocal As New IPEndPoint(IPAddress.Any, LocalPort)
    243. _sockList.Bind(ipLocal)
    244. _sockList.Listen(1)
    245. ChangeState(WinsockStates.Listening)
    246. _sockList.BeginAccept(New AsyncCallback(AddressOf OnClientConnect), Nothing)
    247. Catch ex As Exception
    248. Me.Close()
    249. ChangeState(WinsockStates.Error)
    250. RaiseEvent HandleError(Me, ex.Message, ex.TargetSite.Name, ex.ToString)
    251. End Try
    252. End Sub
    253. Private Sub OnClientConnect(ByVal asyn As IAsyncResult)
    254. Try
    255. Dim tmpSock As Socket
    256. If GetState = WinsockStates.Listening Then
    257. tmpSock = _sockList.EndAccept(asyn)
    258. RaiseEvent ConnectionRequest(Me, tmpSock)
    259. _sockList.BeginAccept(New AsyncCallback(AddressOf OnClientConnect), Nothing)
    260. End If
    261. Catch ex As Exception
    262. Me.Close()
    263. ChangeState(WinsockStates.Error)
    264. RaiseEvent HandleError(Me, ex.Message, ex.TargetSite.Name, ex.ToString)
    265. End Try
    266. End Sub
    267. Private Sub DoStreamReceive(ByVal ar As IAsyncResult)
    268. Dim intCount As Integer
    269. Try
    270. intCount = _Client.EndReceive(ar)
    271. If intCount < 1 Then
    272. Me.Close()
    273. ReDim _byteBuffer(1024)
    274. RaiseEvent Disconnected(Me)
    275. Exit Sub
    276. End If
    277. If IsNothing(_buffer) Then
    278. ReDim Preserve _buffer(intCount - 1)
    279. Array.Copy(_byteBuffer, 0, _buffer, 0, intCount)
    280. Else
    281. ReDim Preserve _buffer((_buffer.Length + (intCount - 1)))
    282. Array.Copy(_byteBuffer, 0, _buffer, (_buffer.Length) - intCount, intCount)
    283. End If
    284. Array.Clear(_byteBuffer, 0, intCount)
    285. If _Client.Available = 0 Then
    286. ' RaiseEvent DataArrival(Me, 0)'<<<<<<< Fehler, da ein Threadübergreifend verursachen wird
    287. CrossThread.RunGui(AddressOf DoDataArrival, 0)
    288. End If
    289. _Client.BeginReceive(_byteBuffer, 0, 1024, SocketFlags.None, AddressOf DoStreamReceive, Nothing)
    290. Catch ex As Exception
    291. Me.Close()
    292. ReDim _byteBuffer(1024)
    293. RaiseEvent Disconnected(Me)
    294. End Try
    295. End Sub
    296. #End Region
    297. Private Sub DoDataArrival(ByVal BytesTotal As Integer)
    298. RaiseEvent DataArrival(Me, BytesTotal)
    299. End Sub
    300. End Class
    301. #Region " Enumerations "
    302. Public Enum WinsockStates
    303. Closed = 0
    304. Open = 1
    305. Listening = 2
    306. ConnectionPending = 3
    307. ResolvingHost = 4
    308. HostResolved = 5
    309. Connecting = 6
    310. Connected = 7
    311. Closing = 8
    312. [Error] = 9
    313. 'Listening = 1
    314. 'Connected = 2
    315. End Enum
    316. #End Region

    "Um keine Threadübergreifend zu verursachen"

    Visual Basic-Quellcode

    1. Public Class CrossThread
    2. Public Shared Sub RunAsync(Of T1, T2, T3)(ByVal Action As Action(Of T1, T2, T3), ByVal Arg1 As T1, ByVal Arg2 As T2, ByVal Arg3 As T3)
    3. ' Aufruf von Action.EndInvoke() gewährleisten, indem er als
    4. ' Callback-Argument mitgegeben wird
    5. Action.BeginInvoke(Arg1, Arg2, Arg3, AddressOf Action.EndInvoke, Nothing)
    6. End Sub
    7. Public Shared Sub RunAsync(Of T1, T2)(ByVal Action As Action(Of T1, T2), ByVal Arg1 As T1, ByVal Arg2 As T2)
    8. Action.BeginInvoke(Arg1, Arg2, AddressOf Action.EndInvoke, Nothing)
    9. End Sub
    10. Public Shared Sub RunAsync(Of T1)(ByVal Action As Action(Of T1), ByVal Arg1 As T1)
    11. Action.BeginInvoke(Arg1, AddressOf Action.EndInvoke, Nothing)
    12. End Sub
    13. Public Shared Sub RunAsync(ByVal Action As Action)
    14. Action.BeginInvoke(AddressOf Action.EndInvoke, Nothing)
    15. End Sub
    16. Private Shared Function GuiCrossInvoke(ByVal Action As [Delegate], ByVal ParamArray Args() As Object) As Boolean
    17. If Application.OpenForms.Count = 0 Then
    18. ' Wenn kein Form mehr da ist, so tun, als ob das Invoking
    19. ' ausgeführt wäre
    20. Return True
    21. End If
    22. If Application.OpenForms(0).InvokeRequired Then
    23. Application.OpenForms(0).BeginInvoke(Action, Args)
    24. Return True
    25. End If
    26. Return False
    27. End Function
    28. Public Shared Sub RunGui(Of T1, T2, T3)(ByVal Action As Action(Of T1, T2, T3), ByVal Arg1 As T1, ByVal Arg2 As T2, ByVal Arg3 As T3)
    29. ' Falls Invoking nicht erforderlich, die Action direkt ausführen
    30. If Not GuiCrossInvoke(Action, Arg1, Arg2, Arg3) Then
    31. Action(Arg1, Arg2, Arg3)
    32. End If
    33. End Sub
    34. Public Shared Sub RunGui(Of T1, T2)(ByVal Action As Action(Of T1, T2), ByVal Arg1 As T1, ByVal Arg2 As T2)
    35. If Not GuiCrossInvoke(Action, Arg1, Arg2) Then Action(Arg1, Arg2)
    36. End Sub
    37. Public Shared Sub RunGui(Of T1)(ByVal Action As Action(Of T1), ByVal Arg1 As T1)
    38. If Not GuiCrossInvoke(Action, Arg1) Then Action(Arg1)
    39. End Sub
    40. Public Shared Sub RunGui(ByVal Action As Action)
    41. If Not GuiCrossInvoke(Action) Then Action()
    42. End Sub
    43. [/spoiler]
    44. End Class

    Danke im Vorraus!

    *Topic verschoben*

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

    Einmal vb.net-Code-Tagging, einmal Visual Basic (6-Style). Siehe Farben. Ne Vereinheitlichung wäre gut, sonst bekommt man ja Augenkrebs. Spoiler wären gut, denn sich freiwillig durch 400 Zeilen Code zu blättern ist mühsam. Ist es wirklich notwendig, mit den ganzen ReDim- und ReDim Preserve -Anweisungen zu arbeiten, wenn man schon bei VB.Net angekommen ist? Isolier doch mal bitte für alle die Client-Receiving-Sub. Denn nur wenige sind gewillt, sich den ganzen Code durchzuschauen, um das passende Fragment zu finden. Als Erläuterung wäre auch gut, wenn wir erfahren, was da gezeigt wird. Server-Code? Client-Code? Beides?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo Leute!
    Sorry das ich die einmal Net und einmal VB-Code-Tagging benutzt habe. Ich habe nicht aufgepasst :S
    und wie es aussieht, war ich nicht ganz bei der Sache, wenn ich sogar Code teil fällt.
    Ihr ist von 1 Codeteil, das obere teil.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Net
    2. Imports System.Net.Sockets
    3. Imports System.ComponentModel
    4. #Region " History "
    5. "
    6. '' 10-20-2005 - Changed buffer mechanism to allow storing of multiple objects
    7. '' Required if you use multiple sends on bitmaps otherwise
    8. '' they stack as one bitmap and don't retrieve properly.
    9. '' Utilizes the EOT (end of transmission) (ascii 4) to do
    10. '' the separating, although it still checks for a count
    11. '' less than the byte length for backwards compatability.
    12. '' - Sending data now appends an EOT at the end of the data
    13. '' 10-19-2005 - Added support for direct byte() sending and retrieving
    14. '' - Added support for bitmap sending and retrieving
    15. '' 08-24-2005 - Released
    16. ''
    17. #End Region
    18. <System.ComponentModel.DefaultEvent("HandleError")> _
    19. Public Class Winsock
    20. Inherits System.ComponentModel.Component

    Der Code stammt von dieser Seite https://www.codeproject.com/Articles/11422/Winsock-NET
    Nun habe ich diesen Codeteil

    VB.NET-Quellcode

    1. If IsNothing(_buffer) Then
    2. ReDim Preserve _buffer(intCount - 1)
    3. Array.Copy(_byteBuffer, 0, _buffer, 0, intCount)
    4. Else
    5. ReDim Preserve _buffer((_buffer.Length + (intCount - 1)))
    6. Array.Copy(_byteBuffer, 0, _buffer, (_buffer.Length) - intCount, intCount)
    7. End If
    8. Array.Clear(_byteBuffer, 0, intCount)
    9. If _Client.Available = 0 Then
    10. ' RaiseEvent DataArrival(Me, 0)'<<<<<<< Fehler, da ein Threadübergreifend verursachen wird
    11. CrossThread.RunGui(AddressOf DoDataArrival, 0)
    12. End If

    Mit diesem Code ausgetauscht

    VB.NET-Quellcode

    1. AddToBuffer(_byteBuffer, intCount)

    VB.NET-Quellcode

    1. Private Sub AddToBuffer(ByVal bytes() As Byte, ByVal count As Integer)
    2. Dim curUB As Integer
    3. If Not _buffer Is Nothing Then curUB = UBound(_buffer) Else curUB = -1
    4. Dim newUB As Integer = curUB + count
    5. ReDim Preserve _buffer(newUB)
    6. Array.Copy(bytes, 0, _buffer, curUB + 1, count)
    7. Dim byterm As Byte = 4
    8. Dim idx As Integer = Array.IndexOf(_buffer, byterm)
    9. Dim byObj() As Byte
    10. Dim byTmp() As Byte
    11. While idx <> -1
    12. 'found an EOT (end of transmission) marker split it if necessary and
    13. 'put it in the buffer to get - call DataArrival
    14. Dim ln As Integer = _buffer.Length - (idx + 1)
    15. ReDim byObj(idx - 1)
    16. ReDim byTmp(ln - 1)
    17. Array.Copy(_buffer, 0, byObj, 0, idx)
    18. Array.Copy(_buffer, idx + 1, byTmp, 0, ln)
    19. ReDim _buffer(UBound(byTmp))
    20. Array.Copy(byTmp, _buffer, byTmp.Length)
    21. Me._bufferCol.Add(byObj)
    22. RaiseEvent DataArrival(Me, byObj.Length)
    23. idx = Array.IndexOf(_buffer, byterm)
    24. End While
    25. If count < bytes.Length - 1 And _buffer.Length > 0 Then
    26. _bufferCol.Add(_buffer)
    27. RaiseEvent DataArrival(Me, _buffer.Length)
    28. _buffer = Nothing
    29. End If
    30. End Sub


    Weil:
    1.) Der oder die Person
    dafür gesorgt hat, das mittels Chr-Code 4 als Splitterung benutzt hat, und somit die, Datei zerstört wurde.
    Und es wurde DataArrival mehr fach ausgelöst, also bei jedem Splitterung und man konnte nicht korrekt wissen wann die Datei vollständig empfangen wurde, um weiter zu machen.
    2.) habe ich Class CrossThread mit eingebunden um den Prozess nicht zu stören, wenn die empfangene Daten wurde, denn wenn ich zum Beispiel
    eine Text-Nachricht an Textbox1 übergeben habe, bekam ich einen Fehler Zitat:"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement TextBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde"
    Ich hoffe das ich es heute richtig gemacht habe, und das ihr mir bitte weiter helfen könnt.

    Mfg Tommy

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tommy“ ()

    Immer noch ReDim und Array.Copy. Na gut, da mich das alles etwas sehr an C-Code erinnert (noch nicht mal C++), muss ich selbst meine Fragen anders stellen:
    Du sagst, dass der Client-Empfangsteil mehrfach Daten bekommt. Heißt das, dass das DataArrival-Event mehrfach aufgerufen wird? Wenn ja, welches (da Du mehrere DataArrival-RaiseEvents hast)? In welcher Sub, in welcher Zeile? Am besten die Zeilennummer angeben, die sie in Deinem geposteten Code hat. (ggf. noch die Postnummer angeben; also bisher: Post#1 oder Post#4. Ist das konstant, dass da 6-7 mal die identischen Daten ankommen oder ist es datenabhängig? Bist Du sicher, dass es die gleichen Daten sind oder wird bei jedem Mal immer etwas mehr übertragen? Im Sinne von: zuerst kommt 12345, dann 123456, dann 1234567, ...
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Hallo VaporiZed!
    es ist so wenn der server angenommen 5120 Byts versendet und der Client hat es empfangen, und hat es verarbeitet, übergibt es mittes Event DataArrival.
    wenn ich es dann Kontrolliere, sind es auch 5120 Byts und die sind auch identisch.
    Aber leider kommt es öfter vor, was meine meinung unlogisch ist. und finde nicht den Fehler.

    Hallo ErfinderDesRades
    Ich möchte dir recht geben, aber ich möchte nicht immer bei einem Projekt den Codesnippsel schrieben, damit ich senden und empfangen kann
    ich möchte mir ein Component schreiben, den ich in jedem Projekt einbinden kann und es soll übersichtlicher geschalten sein wie es unter VB6 üblich war. und es hat mir gut gefallen.
    nun versuche ich es zu kombinieren:
    Es soll leicht zu einbinden und vorallem übersichtlicher sein, nur die technik dahinter soll moderner sein, Sprich es soll auch ipv6 tauglich sein.

    tommy schrieb:

    Aber leider kommt es öfter vor, was meine meinung unlogisch ist. und finde nicht den Fehler.
    Würdest Du auf die gestellten Fragen eingehen, könnten wir Dir auch weiterhelfen.

    Und ob jetzt WinSock oder TCP: Client und Server bleiben doch trotzdem in der Konstellation. Wenn die den geposteten "Schnipsel" immer in Deine Programme einbauen willst, na dann herzlichen Glückwunsch. Modularität lässt sich auch mit TCP erreichen. Ist ja (fast) nur n anderes Übertragungsprotokoll.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Nein WaporiZed
    Es wird nur einmal aufgerufen
    Sehe Codeteil
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub DoStreamReceive(ByVal ar As IAsyncResult)
    2. Dim intCount As Integer
    3. Try
    4. intCount = _Client.EndReceive(ar)
    5. If intCount < 1 Then
    6. Me.Close()
    7. ReDim _byteBuffer(1024)
    8. RaiseEvent Disconnected(Me)
    9. Exit Sub
    10. End If
    11. If IsNothing(_buffer) Then
    12. ReDim Preserve _buffer(intCount - 1)
    13. Array.Copy(_byteBuffer, 0, _buffer, 0, intCount)
    14. Else
    15. ReDim Preserve _buffer((_buffer.Length + (intCount - 1)))
    16. Array.Copy(_byteBuffer, 0, _buffer, (_buffer.Length) - intCount, intCount)
    17. End If
    18. Array.Clear(_byteBuffer, 0, intCount)
    19. If _Client.Available = 0 Then
    20. ' RaiseEvent DataArrival(Me, 0)'<<<<<<< Fehler, da ein Threadübergreifend verursachen wird
    21. CrossThread.RunGui(AddressOf DoDataArrival, 0)
    22. End If
    23. _Client.BeginReceive(_byteBuffer, 0, 1024, SocketFlags.None, AddressOf DoStreamReceive, Nothing)
    24. Catch ex As Exception
    25. Me.Close()
    26. ReDim _byteBuffer(1024)
    27. RaiseEvent Disconnected(Me)
    28. End Try
    29. End Sub


    Aber was mir auch gefallen ist das wenn die Daten vollständig empfangen wurden, wird die Prozedur

    VB.NET-Quellcode

    1. Private Sub DoStreamReceive(ByVal ar As IAsyncResult)
    erneut ausgelöst und ich weiß einfach nicht warum ?(

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

    tommy schrieb:

    VB.NET-Quellcode

    1. Me.Close()
    2. ReDim _byteBuffer(1024)
    3. RaiseEvent Disconnected(Me)
    Ich würde das Me.Close() als letzten Befehl schreiben.
    Wozu dimensionierst Du das Array um, wo doch die Form geschlossen wird?
    =====
    Editiere bitte Deinen 1. Post und pack um den Code einen
    Spoiler anzeigen
    Spoiler.

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo RodFromGermany!
    Ich möchte dich kurz ausbessern es ist kein Formular sondern ein Component Modul.
    Dieser Codeteil

    VB.NET-Quellcode

    1. If intCount < 1 Then
    2. Me.Close()
    3. ReDim _byteBuffer(1024)
    4. RaiseEvent Disconnected(Me)
    5. Exit Sub
    6. End If

    Steht glaub ich deswegen nicht am schloss, wenn die Variable intCount <1, das da etwas nicht korrekt ist, und somit die Verbindung geschlossen wird.
    ich habe es schon bei viele seiten so gesehen das dies so geschrieben wird. genau weiß ich es auch nicht sorry
    Bevor ich weiter durch den Option Strict Off/VisualBasic-Namespace-Code durchwate: Wie nutzt Du diese Klasse? Im Sinne von: Gib mal bitte das kürzeste Code-Beispiel für Server UND Client, was zu einer Verbindung und erfolgreichen (wenn auch multiplen) Datenübertragung führt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    my 5 ct:
    Wir wissen es schlicht nicht.
    Warum de blöde Socket eine Datei mehrmals empfängt, obwohl sie nur einmal gesendet wurde.

    Das das Teil darüber hinaus auch gegen einige best-practices verstößt ist sicher richtig und verbesserungswürdig, aber zielgerichtete Vorschläge zur Korrektur des Fehlverhaltens sind das nicht.
    Aber kann immer noch sein, dass dabei Heilung eintritt - derlei "Zufallstreffer" bei allgemeinen Code-Verbesserungen sind nicht ungewöhnlich.

    jdfs gute Idee, die Benutzung von dem mal zu üprüfen - vlt. wird die Datei ja tatsächlich mehrmals gesendet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ich habe das Problem gefunden
    ich hatte mich auf

    VB.NET-Quellcode

    1. If _Client.Available = 0 Then
    verlassen, denn durch Tests wo ich kleine Dateien versendet habe, hat Available korrekt gearbeitet immer wenn ein Paket gekommen ist, war Available wert höher als 0.
    Aber als ich größere Datei wie MP3 versendet habe, hatte Available zwischen durch auch null, obwohl es nicht fertig war.
    Jetzt habe ich einen Header mit eingebaut, um Information zugeben wie groß die Datei sein muss.
    Und sehe da, es funktioniert PRIMA.
    Aber ein kleines Problem habe ich noch, wo bei mir auch noch ein Zitat
    Immer noch ReDim und Array.Copy
    von VaporiZed Bauchschmerzen brachte.
    Nun weiß ich von das er redete
    wird die Arrays nach und nach vergrößere und die Daten rein kopiere wird er immer langsamer vor allem bei größeren Dateien.
    Wie
    stelle ich es richtig an, damit ich die Byte-Arrays nach und nach, die
    Daten hinzufüge, wenn die Daten ankommen, ohne das es mit der zeit
    langsamer wird?
    Mfg Tommy
    @tommy Es ist schon mehrfach angesprochen worden, wir wiederholen uns ungern:

    VaporiZed schrieb:

    Spoiler wären gut, denn sich freiwillig durch 400 Zeilen Code zu blättern ist mühsam.

    RodFromGermany schrieb:

    Editiere bitte Deinen 1. Post und pack um den Code einen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    tommy schrieb:

    Wie stelle ich es richtig an, damit ich die Byte-Arrays nach und nach, die Daten hinzufüge, wenn die Daten ankommen, ohne das es mit der zeit langsamer wird?
    Dein Satz spottet zwar den Regeln der deutschen Sprache, aber ich glaub ich weiß, was du meinst.
    Also um beliebig grosse Datenmengen zu bewegen sind die Streams erfunden worden.
    Ein Stream ist eine Klasse, wo man auf einer Seite Daten hineinschreibt, und auf der anderen Seite kommen sie wieder raus. Intern besitzt er eine korrekte Puffer-Implementierung, und das ist wohl der Punkt: Dein Winsock-Dingens hat zwar _Buffer / _ByteBuffer - Arrays, aber was damit getrieben wird kann man eiglich nicht wirklich als Pufferung im engeren Sinne bezeichnen.

    Da hier die Daten-Bewegung übers Internet erfolgt ist hier die NetworkStream-Klasse Stream der Wahl.
    Aber du willst dich ja auf Deibel komm raus nicht auf moderne .Net-Konzepte einlassen - TcpClient heisst die Klasse, die Networkstreams bereitstellt.

    So ist das halt in .Net: Wenn du ein Grundkonzept verstanden hast, kannst du es auf einmal auf viele Probleme anwenden. Daher musste "nur" das Stream-Konzept verstehen, und dann kannst du auch mit Networkstreams umgehen.

    Bei Interesse gugge Streams