【发布时间】:2012-03-21 05:39:45
【问题描述】:
我有一个名为 SocketSvr 的类,它处理异步套接字服务器。它是通过我的主窗体中的 BackgroundWorker 调用的。基本上,我只希望它在主窗体的文本框中显示我的套接字数据信息,并在主窗体上有一个服务器启动/停止按钮来执行这些操作。
这是来自 Form1.vb 的代码:
Public Class Form1
Dim WithEvents Socketsvr As New SocketSvr
Private Sub ToggleServerButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ToggleServerButton.Click
If ToggleServerButton.Text = "Stop Server" Then
ToggleServerButton.Text = "Start Server"
Socketsvr.StopServer()
Else
ToggleServerButton.Text = "Stop Server"
Socketsvr.StartServer()
End If
End Sub
Private Sub UpdateOutput_Event(ByVal sender As Object, _
ByVal text As String) Handles Socketsvr.UpdateOutput
Me.ServerOutputTextbox.AppendText(text + vbCrLf)
End Sub
End Class
上面很简单,基本上都是调用StartServer()或者StopServer()函数。下面的事件是一个引发事件,我使用它通过后台进程调用的事件来更新文本框。
以下是 Socketsvr.vb 的一些代码——我删除了不相关的代码以尽量减少帖子的废话。
Public Sub StopServer()
bw.CancelAsync()
allDone.Set()
End Sub 'StopServer
Public Sub StartServer()
bw.WorkerSupportsCancellation = True
bw.RunWorkerAsync()
End Sub 'StartServer
Private Sub bw_DoWork(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
' Data buffer for incoming data.
Dim bytes() As Byte = New [Byte](1023) {}
' Establish the local endpoint for the socket.
Dim ipHostInfo As New IPHostEntry
ipHostInfo.AddressList = New IPAddress() _
{New IPAddress(New [Byte]() {127, 0, 0, 1})}
Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
Dim localEndPoint As New IPEndPoint(ipAddress, 8888)
' Create a TCP/IP socket.
Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
' Bind the socket to the local endpoint and listen for incoming connections.
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1)
listener.Bind(localEndPoint)
listener.Listen(100)
While True
' If cancellation is pending, shut down server
If bw.CancellationPending Then
Out("Server stopped at " + DateTime.Now.ToString())
Exit While
End If
Out("Server started at " + DateTime.Now.ToString())
' Set the event to nonsignaled state.
allDone.Reset()
Try
' Start an asynchronous socket to listen for connections.
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)
Catch ex As Exception
MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
' Wait until a connection is made and processed before continuing.
allDone.WaitOne()
End While
End Sub
我不确定如何在 StopServer() 函数运行时正确关闭来自客户端的请求。在上面的代码中,我为后台进程放置了一个取消队列。有趣的是,一旦 StopServer() 运行,它会再接受一个连接,然后停止接受。
如果我从上面的代码中删除以下行:
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1)
--当我第二次尝试启动服务器时它崩溃了(抱怨我不能重用套接字,显然)我的猜测是我需要在后台工作人员的 bw.CancellationPending 调用中添加一些东西?
任何见解都将不胜感激,如果我需要更多信息,请告诉我。
【问题讨论】:
标签: vb.net sockets asynchronous backgroundworker