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

客户端部分的问题在服务器上是相同的。断开客户端与服务器的代码不起作用。在我按下断开按钮后,它不会向服务器发送任何日志,即使我之后重新连接也是如此。好像socket已经被处理掉了?如果是这样,当我尝试重新连接时,如何防止它这样做并重用套接字?另一件事是,当我按下连接按钮而不启动服务器然后启动服务器时,会向客户端连接的服务器发送一条日志。似乎问题出在服务器的监听方法上。我不希望这种情况发生,我只想要一个异常或提醒用户客户端未连接到服务器并且在客户端连接后不向服务器发送日志消息的东西。我真的不知道,

提前致谢!

4

1 回答 1

0

更好的方法是实现标志系统。当一个客户端或服务器想要与另一端断开连接时,将断开标志发送到另一端,因此在另一端您的代码将理解断开连接

于 2013-01-08T09:54:56.417 回答