正确断开和重新连接异步连接

时间:2013-01-08 07:30:22

标签: vb.net sockets asyncsocket

我目前正在使用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

客户端部分的问题在服务器上是相同的。断开客户端与服务器的连接的代码不起作用。按下断开连接按钮后,即使我之后重新连接,它也不会向服务器发送任何日志。套接字似乎已被处理?如果是这样,我怎么能阻止它这样做并在我尝试重新连接时重用套接字?另一件事是,当我按下连接按钮而不启动服务器并随后启动服务器时,会将日志发送到客户端连接的服务器。似乎问题出在服务器的listen方法上。我不希望这种情况发生,我只是想要一个例外或者某些事情会提醒用户客户端没有连接到服务器,并且在客户端连接之后不向服务器发送日志消息。我真的不知道,但你认为如果我将listen方法的积压设置为零会阻止这种情况发生吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

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