나는 또한 reddit에 대한 질문에 답변했지만, 다른 누군가가 이런 종류의 것을 찾고있는 경우에 나는 여기에 답장을 할 것이라고 생각했습니다.
서버가 읽기를 처리하는 방식에는 두 가지 문제가 있습니다. 우선, 클라이언트 객체의 생성자 :
Public Sub New(ByVal client As TcpClient)
'New client connects
Me.client = client
client.GetStream().BeginRead(New Byte() {0}, 0, 0, AddressOf Read, Nothing)
End Sub
그러면 BeginRead 당신이 콜백 메소드에 건네 줄 수있는 방법으로 데이터를 수집 할 것으로 예상; 이 경우 "읽기". 일반적으로이 비동기 작업의 "상태"를 보유 할 새 개체를 만들고이를 BeginRead의 마지막 매개 변수로 전달하면됩니다. 메서드 호출은 새로운 바이트 배열을 만드는 것이지만 메서드에 대한 마지막 인수로 전달할 참조를 보유하지 않습니다. 즉,이 호출에 의해 읽혀진 데이터는 읽은 후에 사라지게됩니다. 왜냐하면 결코 그것을 저장하는 메소드로 전달되지 않기 때문입니다. 둘째
, 당신의 읽기 동작 :
Public Sub Read(ByVal ar As IAsyncResult)
Dim reader As New StreamReader(client.GetStream())
clientPacket &= reader.ReadLine()
client.GetStream().BeginRead(New Byte() {0}, 0, 0, AddressOf Read, Nothing)
End Sub
당신이, 당신은 클라이언트에서 더 많은 데이터를 끌어 여기에 새에서는 StreamReader를 만드는 비동기 호출에서 읽은 데이터를 전달하지 않는 때문에 . 이것은 비동기 메서드 호출이 아닙니다. reader.ReadLine() 호출은 개행 문자가 나올 때까지 차단되어 그 시점에서 데이터가 clientPacket에 추가됩니다. 위에서 언급 한 것과 동일한 문제로 BeginRead를 다시 호출하면 더 많은 데이터가 손실됩니다.
또한 스트림에서 EndRead()를 호출하여 AsyncResult 개체를 지우지 않아 비동기 작업에 대한 작업자 스레드가 CLR에서 부족 해지면 결국 자원 고갈이 발생합니다.
다음은 이러한 종류의 작업을 구현하는 방법의 예입니다. 그것은 C#에 있습니다. 왜냐하면 그것이 내가 가장 편안하다고 생각하기 때문에, 정말 미안합니다. ;)
Client Code
Server Code
난이 도움이되기를 바랍니다!
감사합니다. 작동하도록하십시오! – Scyte