最近做一个数据采集器的服务器软件,数据采集器客户端采集到的数据是通过以太网传输到主机上的。由于时间紧,加上以前我有一点VB6的编程基础,我就用vb.net开发。用的控件还是VB6中的Winsock控件。
在vb.net中要使用Winsock控件有两种方法:第一,就是先安装VB6,然后在vb.net的选项卡中,就可以添加Winsock控件了;第二,是先找到Winsock的文件mswinsck.ocx,复制到windows/system32/目录下,并注册。这样就可以使用Winsock控件了。
我做的服务器用TCP传输,主要的控件有以下几个:一个按钮“btReceiveState”,一个Winsock“wskRtDatReceive”,两个TextBox“tbRemoteIP”和“tbRemotePort”
'-------------------------------------------------------------------
'点击“接收”按钮响应函数
'-------------------------------------------------------------------
Private Sub btReceiveState_Click(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles btReceiveState.Click
'当“开始接收”时
If bLinkState = False Then
'参数过滤,防止有不正确的参数
If tbRemoteIP.Text = "" Then
MsgBox("请输入IP地址",MsgBoxStyle.Critical,"Error!")
Exit Sub
End If
If nudRemotePort.Value < 1024 Or nudRemotePort.Value > 65535 Then
MsgBox("端口号的范围应该在1024-65535之间,请重新输入","Error!")
nudRemotePort.Value = 1024
Exit Sub
End If
Try
'设置以太网参数,使用TCP连接,本地端口号为7777
wskRtDatReceive.Protocol = MSWinsockLib.ProtocolConstants.sckTCPProtocol
wskRtDatReceive.LocalPort = 7777
'监听端口
wskRtDatReceive.Listen()
Catch ex As Exception
MsgBox(ex.ToString)
Exit Sub
End Try
'改变“接收”按钮状态
btReceiveState.Text = "停止接收"
bLinkState = True
'当“停止接收”时
Else
Try
'关闭以太网口
wskRtDatReceive.Close()
Catch ex As Exception
MsgBox(ex.ToString)
Exit Sub
End Try
'改变“接收”按钮状态
btReceiveState.Text = "开始接收"
bLinkState = False
End If
End Sub
#Region "以太网传输相关"
'-------------------------------------------------------------------
'客户端请求以太网传输,TCP的连接事件响应函数
'-------------------------------------------------------------------
Private Sub wskRtDatReceive_ConnectionRequest(ByVal sender As Object,ByVal e As AxMSWinsockLib.DMSWinsockControlEvents_ConnectionRequestEvent) Handles wskRtDatReceive.ConnectionRequest
If wskRtDatReceive.RemoteHostIP <> tbRemoteIP.Text Then
MsgBox(wskRtDatReceive.RemoteHostIP & " " & wskRtDatReceive.RemotePort & "请求被拒绝")
Exit Sub
End If
If wskRtDatReceive.RemotePort <> nudRemotePort.Value Then
MsgBox(wskRtDatReceive.RemoteHostIP & " " & wskRtDatReceive.RemotePort & "请求被拒绝")
Exit Sub
End If
Try
If wskRtDatReceive.SocketHandle <> -1 Then
wskRtDatReceive.Close()
End If
wskRtDatReceive.Accept(e.requestID)
Catch ex As Exception
MsgBox(ex.ToString)
Exit Sub
End Try
End Sub
'-------------------------------------------------------------------
'以太网,接收事件响应函数
'-------------------------------------------------------------------
Private Sub wskRtDatReceive_DataArrival(ByVal sender As Object,ByVal e As AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent) Handles wskRtDatReceive.DataArrival
wskRtDatReceive.GetData(tbRdTest.Text)
End Sub
#End Region
这里着重说明,蓝色代码的地方:
第一,是与VB6不同,vb.net将事件发生后所要传递的变量都放在e这个结构体中,并且作为第二个参数传递给事件响应函数,例如:
Private Sub wskRtDatReceive_ConnectionRequest(ByVal sender As Object, ByVal e As AxMSWinsockLib.DMSWinsockControlEvents_ConnectionRequestEvent) Handles
调用:
wskRtDatReceive.Accept(e.requestID)
第二,是在使用Winsock的Accept方法时一定要先判断winsock的状态,以前在vb6中,使用State属性,现在使用SocketHandle属性,如果不等于-1,说明winsock的状体不是关闭状态,就调用Close方法,如
If wskRtDatReceive.SocketHandle <> -1 Then
wskRtDatReceive.Close()
End If
wskRtDatReceive.Accept(e.requestID)
否则会无法正确接收连接请求。
第三,是接收数据的GetData函数与VB6中的,有较大区别,(虽然我的程序没有用到区别之处)
在vb6中,可以在WinsockControlName_DataArrival中使用,如下语句接收
Dim ReadMsg As String
WinsockControlName.GetData ReadMsg
但是,在vb.net中上面语句会产生错误,在vb.net中,使用如下语句会达到同样的效果
Dim ReadMsg As ObjectWinsockControlName.GetData(ReadMsg,vbString,1500)