VB服务器长连接实现

前端之家收集整理的这篇文章主要介绍了VB服务器长连接实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

使用VB的Winsock控件,完成公司一个小Demo。

期间遇到很多问题,此处整理如下

一. winsock控件的用法

添加控件: 工程-部件- Microsoft Winsock Control 6.0

拖一个控件出来命名为winsock1

做客户端时

winsock1.RemoteHost = "127.0.0.1"'目标服务器的IP地址,(此处测试用本地IP)
winsock1.RemotePort = 15555'目标服务器的指定端口号
winsock1.Connect '连接
在winsock1_Connect事件中发送数据
winsock1.SendData (strdata)‘发送字符串数据

做服务器端时:(主要用来监听客户端通过端口发过来的数据)

流程:设定监听--接收请求连接并发送连接ID--接收数据--继续监听

winsock1.LocalPort = 15555  '设定监听端口
winsock1.Listen '开启监听
在winsock1_ConnectionRequest(ByVal requestID As Long) 事件中做如下处理
winsock1.Accept requestID'对客户端的连接请求做回应
在winsock1_DataArrival(ByVal bytesTotal As Long)事件中处理接收到的数据
'该事件为winsock控件接收到缓存数据并通知客户的功用,bytesTotal为缓存数据长度,获取数据用GetData()函数
winsock1.GetData strdata‘以字符串格式接收具体数据
'继续监听前需做关闭处理,因为winsock控件处于监听状态时,该控件接收一次数据后,自动转为连接状态,此时不再有监听功能
'故此处续作如下处理
If winsock1.State <> sckClosed Then winsock1.Close'通过连接状态判断连接情况,关闭控件
   winsock1.Listen '重新开启监听

二. 服务器端处理(本项目主要是服务器端需求,客户端不再分析处理,可参考)

需求:1. 接收客户端每4s发送一次的连接请求 2. 发送一个确认连接二进制字符 3. 开始长连接接收数据

1. 客户端的4s请求接收,按照第一部分标题处理服务器端的操作,出问题了。服务器会持续不断的接收到请求数据,并不停的刷数据。

经多方查找总算找到解决方案了:生成两个控件sckListen、sckServer,一个用于监听一个用于接收数据。这种情况下监听的winsock控件状态一直为监听状态不会断开也不会改变,sckServer用于接收数据并用于以后的长连接等等功用。

实现如下:

sckListen.LocalPort = 15555 ‘设定监听端口
sckListen.Listen '开启监听
在sckListen_ConnectionRequest(ByVal requestID As Long) 事件中做如下处理
sckServer.Accept requestID		'对客户端的连接请求做回应【此处请求用sckServer回应】
在sckServer_DataArrival(ByVal bytesTotal As Long)事件中处理接收到的数据
sckServer.GetData strdata‘以字符串格式接收具体数据
及此如上需求的第一个问题就实现了,sckListen每个4s监听到一条数据请求,由sckServer回复请求连接,再接收数据,处理即结束。

2. 发送一段二进制字符 主要难点在二进制字符的生成及转化上,以及winsock发送二进制数据的方式

'十六进制字符串转byte()形式
Function HexToByte(str As String) As Byte()
    Dim rst() As Byte
    Dim i As Long,j As Long
    i = Len(str)
    j = i \ 2 - 1
    ReDim rst(j)
    For i = 0 To j
        rst(i) = CByte("&H" & Mid$(str,i + i + 1,2))
    Next
    HexToByte = rst()
End Function
使用过程如下
    Dim RequestYES() As Byte
    RequestYES = HexToByte("00400F000000000000000000")
    
    For i = 0 To UBound(RequestYES) - LBound(RequestYES)
        sckServer.SendData RequestYES(i)
    Next
使用sckServer发送二进制数据,建立长连接。

3. 长连接数据接收部分

长连接在建立之后开始持续接收。此时监听控件sckListen就收不到监听请求连接了。此时的长连接数据就在sckServer的sckServer_DataArrival事件中进行接收处理。

此处项目的主要难点是接收到的数据包,包含4字节的OrderID以及4字节的数据长度。此处就需要编写数据截取以及byte数据转化的情况了。

如下方式接收byte数组数据:

    Dim bytedata() As Byte
    sckServer.GetData bytedata()
byte数组截取实现:
'byte()数组赋值问题
Public Function CopyArrayBytes(bits() As Byte,pos As Integer,count As Long) As Byte()
    Dim Res() As Byte
    Dim i As Integer
    Dim j As Integer
    Dim iend As Integer
    
    iend = UBound(bits) - LBound(bits) + 1
    iend = IIf(iend < (pos + count),iend,pos + count)
    ReDim Res(iend - 1 - pos)
    j = 0
    For i = pos To (iend - 1)
        Res(j) = bits(i)
        j = j + 1
    Next
    CopyArrayBytes = Res
End Function
byte数组数据转化:
'十六进制字符串转byte()形式
Function HexToByte(str As String) As Byte()
    Dim rst() As Byte
    Dim i As Long,2))
    Next
    HexToByte = rst()
End Function
4位字节转整形数据:(此处源数据为小端输出,如为小端模式则反向转换)
'4位byte值转int型值
Function ByteToInteger(bits() As Byte) As Long
    Dim x As Long
    x = CLng(bits(0)) + CLng(bits(1)) * 256 + CLng(bits(2)) * 65536 + CLng(bits(3)) * 16777216
    ByteToInteger = x
End Function
'byte()转十六进制string形式
Public Function BytesToHex(bits() As Byte) As String
    Dim i As Long
    Dim b
    Dim s As String
    For Each b In bits
        If b < 16 Then
            s = s & "0" & Hex(b)
        Else
            s = s & Hex(b)
        End If
    Next
    BytesToHex = s
End Function

三、最后说明一些边角问题

1. 本程序仅用于Demo,故只做了一个客户端的连接及监控,如需做多客户端的,需在sckListen_ConnectionRequest(ByVal requestID As Long)事件中加载多客户端控件,然后分配连接。改代码框架可百度自行搜索

2. 获取客户端的IP,用sckListen.RemoteHostIP获取客户端IP。

猜你在找的VB相关文章