1

現在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 メソッドにあるようです。クライアントがサーバーに接続されていないことをユーザーに警告し、クライアントが接続した後にサーバーにログメッセージを送信しない例外または何かが必要です。私は本当に知りません、

前もって感謝します!

4

1 に答える 1

0

これを行うより良い方法は、フラグ システムを実装することです。あるクライアントまたはサーバーが他のクライアントまたはサーバーから切断したい場合、切断フラグを他の端に送信するため、他の端でコードが切断を理解します

于 2013-01-08T09:54:56.417 に答える