VisualBasicでTCP/IPリスナーを作成しようとしています。リスナーは、いつでも接続している多くの異なるクライアントを処理できる必要があります。私が開発したコードは、
socket.BeginAcceptSocket()
方法。これまで見てきたほとんどの例から、新しい接続をリッスンし、受信して処理し、そのソケットでの受け入れを停止し、データを処理してから、接続を閉じます。データの受信と処理を処理するために生成したスレッドは正しく閉じられ、処理されます。
ただし、何らかの理由で、BeginAcceptSocketメソッド用に作成されるスレッドの数が無限になっているようです。これにより、コンピューターの速度が低下し、最終的にはロックされ、クライアントなどからデータが失われ始めます。ここにコードを投稿しますが、基本的に、ここで間違っていることが明らかなことはありますか?私は静かに少し時間をかけて検索し、これをデバッグしようとしましたが、かなり行き詰まっています。
Imports System.Net.Sockets, System.Threading, System.IO, System.Net
Imports System.Text
Imports System.Data, System.Data.SqlClient
Module Module1
'The Tcp listener listening on port 2012
Dim listener As New TcpListener(IPAddress.Any, 2012)
'Signal for when to start listening on a new socket for a client
Private clientConnected As New ManualResetEvent(False)
'The threads being used for the processing
Private listenThread, test As Thread
Sub Main()
listener.Start()
listenThread = New Thread(AddressOf doListen)
listenThread.IsBackground = True
listenThread.Start()
Do
Select Case Console.ReadLine().ToLower
Case "exit"
Exit Do
End Select
Loop
End Sub
Sub message(ByVal msg As String)
msg.Trim()
Console.WriteLine(">> " + msg)
End Sub
Sub doListen()
'Reset the signal
clientConnected.Reset()
Do
'Start listening for new Sockets, upon a new socket create a new thread @ AcceptClients
listener.BeginAcceptSocket(New AsyncCallback(AddressOf AcceptClients), listener)
'Wait for the new socket to be handled
clientConnected.WaitOne()
'Reset the flag and then repeat
clientConnected.Reset()
Loop
End Sub
Sub AcceptClients(ar As IAsyncResult)
'Get the listener that handles the request
Dim listen As TcpListener = CType(ar.AsyncState, TcpListener)
'Create a new socket and end the listening on that socket
Dim clientSocket As Socket = listen.EndAcceptSocket(ar)
'Notify the main thread that it is ready to listen for new connections
clientConnected.Set()
'Define variables used for lisetning and parsing messages
Dim byteRec(1024) As Byte
Dim message As String = Nothing
Dim N, C As Integer
Dim lengthFound As Boolean = False
Dim finished As Boolean = False
Do
Try
Dim intBytes As Int32 = clientSocket.Receive(byteRec, 0, clientSocket.Available,
SocketFlags.None)
message = ASCIIEncoding.ASCII.GetString(byteRec, 0, intBytes)
If intBytes > 0 Then ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf printMsg), message)
'If message.Contains(Chr(1)) And Not lengthFound Then
' 'Call method to return the total number of messages in the group
' N = getNumber(message, message.IndexOf(Chr(1)) + 1)
' lengthFound = True
'End If
'C = getCountOfMessages(message)
'If getCountOfMessages(message) = N And lengthFound Then
' finished = True
' Exit Do
'End If
While intBytes > 0 And Not finished
intBytes = clientSocket.Receive(byteRec, 0, clientSocket.Available, SocketFlags.None)
message = ASCIIEncoding.ASCII.GetString(byteRec, 0, intBytes)
'Somehow need to look for the number of STX's and increment the counter by each number
'C = getCountOfMessages(message)
'If message.Contains(Chr(1)) And Not lengthFound Then
' 'Call method to return the total number of messages in the group
' N = getNumber(message, message.IndexOf(Chr(1)) + 1)
' lengthFound = True
'End If
'If getCountOfMessages(message) = N And lengthFound Then
' finished = True
' Exit Do
'End If
End While
Catch ex As Exception
End Try
Loop
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf printMsg), message)
clientSocket.Close()
clientSocket.Dispose()
End Sub
'Method to return the total number of messages RECEIVED from a group
Function getCountOfMessages(ByVal message As String)
Dim C As Integer = 0
C = message.Split(Chr(2)).Count - 1
Return C
End Function
'Method to return the total number of messages in a group. Paramters are the total message string and the index of the SOH char
Function getNumber(ByVal message As String, ByVal index As Integer)
Dim N As Integer = 0
'Create a loop to start at the SOH and convert all data between SOH and ETX to N as an integer and return it
Dim S As Boolean = True
Dim temp As String = ""
While S
Select Case message(index)
Case Chr(3)
'End of message is found, exit loop
S = False
Case Else
'Add the data between the SOH and ETX to a string. Once finished convert the data to an int
' The reason I think this is neccessary would be in case we decide to have more than 9 messages, aka 2 or more digit numbers. like 10 or 300 etc..
temp = temp + message(index)
End Select
index = index + 1
End While
N = Convert.ToInt32(temp)
Return N
End Function
'This method will be used to reorder, parse and delimt the messages then add them into the SQL database
Sub printMsg(ByVal msg As Object)
Dim dataStr As String = ""
Debug.Print(msg & vbCrLf)
End Sub
End Module
どんな助けでも大歓迎です。