現在VB.Netで非同期通信を利用したファイル共有アプリを開発中です。クライアントとサーバー間の単純な接続をコーディングすることに成功しました。しかし、現在、クライアントとサーバーの両方の切断サブルーチンを実行するのに苦労しています。私は現在、この問題で数日間立ち往生しており、切断を行う良い方法が見つからないため、ここで助けを求めることにしました.
これが私のコードです:
サーバー アプリケーション
Private Sub FileSharingInitialize()
ServerSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim EndPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 7777)
ServerSocket.Bind(EndPoint)
ServerSocket.Listen(0)
End Sub
Private Sub FileSharingOnAccept(ByVal AsyncResult As IAsyncResult)
ClientSocket = ServerSocket.EndAccept(AsyncResult)
FileSharingAddClient(ClientSocket)
ClientSocket.BeginReceive(ByteData, 0, ByteData.Length, SocketFlags.None, New AsyncCallback(AddressOf FileSharingOnReceive), ClientSocket)
End Sub
Delegate Sub _FileSharingAddClient(ByVal Client As Socket)
Private Sub FileSharingAddClient(ByVal Client As Socket)
If InvokeRequired Then
Invoke(New _FileSharingAddClient(AddressOf FileSharingAddClient), Client)
Exit Sub
End If
lvConnectedClients.Items.Add("")
lvConnectedClients.Items(lvConnectedClients.Items.Count - 1).SubItems.Add(Client.LocalEndPoint.ToString)
End Sub
Private Sub FileSharingOnReceive(ByVal AsyncResult As IAsyncResult)
Dim Client As Socket = CType(AsyncResult.AsyncState, Socket)
Client.EndReceive(AsyncResult)
Dim ByteReceived As Byte() = ByteData
Dim LogMessage As String = System.Text.Encoding.ASCII.GetString(ByteReceived)
ReadLogMessage(LogMessage)
End Sub
Delegate Sub _ReadLogMessage(ByVal LogMessage As String)
Private Sub ReadLogMessage(ByVal LogMessage As String)
If InvokeRequired Then
Invoke(New _ReadLogMessage(AddressOf ReadLogMessage), LogMessage)
Exit Sub
End If
DisplayLogMessage(LogMessage)
End Sub
Private Sub DisplayLogMessage(ByVal Log As String)
Dim TimeStamp As String = "[" & DateAndTime.Now.ToString("hh:mm:ss tt dddd, dd MMMM yyyy") & "]: "
Dim LogMessage As String = ""
If txtLog.Text > "" Then
LogMessage = Chr(10) & Chr(13)
End If
LogMessage &= TimeStamp
LogMessage &= Log
txtLog.SelectionStart = Len(txtLog.Text)
txtLog.SelectedText = LogMessage
End Sub
Private Sub frmMain_Load(sender As Object, e As System.EventArgs) Handles Me.Load
FileSharingInitialize()
End Sub
Private Sub btnStart_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnStart.MouseClick
ServerSocket.BeginAccept(New AsyncCallback(AddressOf FileSharingOnAccept), Nothing)
DisplayLogMessage("Server started." & Environment.NewLine)
End Sub
サーバー側では、停止ボタンを押したときに、すべてのクライアントをサーバーから切断したいと考えています。スタートボタンでこのコードを試しましたが、うまくいきません。ソケットが接続されていないというエラーが表示されます。サーバーアプリケーションに ClientSocket という名前のソケットもあるため、間違ったソケットを切断している可能性があると考えています。それとも、ループでクライアントを切断する必要がありますか? どう思いますか?
Private Sub btnStop_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnStop.MouseClick
ServerSocket.Shutdown(SocketShutdown.Both)
ServerSocket.Close()
ServerSocket = Nothing
End Sub
クライアント アプリケーション
Private Sub btnConnect_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnConnect.MouseClick
ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim Address As IPAddress = IPAddress.Parse(frmNetworkSettings.txtServerIPAddress.Text)
Dim Endpoint As IPEndPoint = New IPEndPoint(Address, CInt(frmNetworkSettings.txtFileSharingPort.Text))
ClientSocket.BeginConnect(Endpoint, New AsyncCallback(AddressOf FileSharingOnConnect), Nothing)
SendLogMessage(Username & " is connected." & Environment.NewLine, ClientSocket)
End Sub
Private Sub FileSharingOnConnect(ByVal AsyncResult As IAsyncResult)
ClientSocket.EndConnect(AsyncResult)
End Sub
Private Sub SendLogMessage(ByVal LogMessage As String, ByVal Client As Socket)
Dim SendByteData As Byte() = System.Text.Encoding.ASCII.GetBytes(LogMessage)
Client.BeginSend(SendByteData, 0, SendByteData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSendLogMessage), Client)
End Sub
Private Sub OnSendLogMessage(ByVal AsyncResult As IAsyncResult)
Dim Client As Socket = CType(AsyncResult.AsyncState, Socket)
Client.EndSend(AsyncResult)
End Sub
クライアント側の問題はサーバーでも同じです。クライアントをサーバーから切断するコードが機能しません。切断ボタンを押した後、後で再接続しても、サーバーにログが送信されません。ソケットが処分されたようですか?もしそうなら、どうすればそれを防ぎ、再接続しようとしたときにソケットを再利用できますか? もう1つのことは、サーバーを起動せずに接続ボタンを押してからサーバーを起動すると、クライアントが接続したサーバーにログが送信されることです。問題はサーバーの listen メソッドにあるようです。クライアントがサーバーに接続されていないことをユーザーに警告し、クライアントが接続した後にサーバーにログメッセージを送信しない例外または何かが必要です。私は本当に知りません、
前もって感謝します!