打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
VB6+Winsock编写的websocket服务端

早就写好了,看这方面资料比较少,索性贴出来.只是一个DEMO中的,没有做优化,代码比较草.由于没地方上传附件,所以只把一些主要的代码贴出来.

这只是服务端,不过客户端可以反推出来,其实了解了websocket协议就简单多了...开始了...

请求头构造:

       req_heads = "HTTP/1.1 101 Web Socket Protocol Handshake" & vbCrLf    req_heads = req_heads & "Upgrade: websocket" & vbCrLf    req_heads = req_heads & "Connection: Upgrade" & vbCrLf    req_heads = req_heads & "Sec-WebSocket-Accept: [KEY]" & vbCrLf    req_heads = req_heads & "WebSocket-Origin: [ORGN]" & vbCrLf    req_heads = req_heads & "WebSocket-Location: [HOST]" & vbCrLf & vbCrLf

Winsock接收部分:

Private Sub SerSock_DataArrival(Index As Integer, ByVal bytesTotal As Long)Dim s As StringDim b() As ByteDim i As LongShowlog Index & "bytesTotal:" & bytesTotal    SerSock(Index).GetData bIf Client(Index) Then'判断该客户端是否进行过验证Dim k As StringDim rs As Strings = StrConv(b, vbUnicode)        k = Trim(MidEx(s, "Sec-WebSocket-Key:", vbCrLf))If Len(k) <> 0 Thenk = AcceptKey(k)            rs = Replace(woshou, "[KEY]", k)            k = Trim(MidEx(s, "Origin:", vbCrLf))            rs = Replace(rs, "[ORGN]", k)            k = Trim(MidEx(s, "Host:", vbCrLf))            rs = Replace(rs, "[HOST]", k)            Client(Index).SendData rs            bool(Index) = FalseEnd IfElseIf b(0) = &H81 ThenIf PickData(b) = True ThenFor i = 0 To Client.Count - 1If Client(i).State = 7 Then Client(i).SendData bNext iEnd IfElseFor i = 0 To UBound(b)                s = s & b(i) & " "Next i            Showlog ">>> " & sEnd IfEnd IfEnd SubPrivate Function PickData(byt() As Byte) As BooleanDim i As LongDim mask(3) As ByteDim bData() As ByteDim Lb(3) As ByteDim L As LongDim inx As Long '偏移Dim sti As LongDim s As Stringi = UBound(byt) - 3ReDim b(i)    b(0) = 62b(1) = 62L = byt(1) Xor &H80 '128If L < 126 ThenIf UBound(byt) <> L + 5 Then Exit FunctionIf L < 125 Then '            ReDim bData(L + 2)ElseReDim bData(L + 1): L = L - 1End If'        ReDim bData(L)bData(0) = &H81        bData(1) = CByte(L + 1)        CopyMemory mask(0), byt(2), 4inx = 6sti = 2ElseIf L = 126 ThenLb(0) = byt(3)        Lb(1) = byt(2)        CopyMemory L, Lb(0), 4If UBound(byt) <> L + 7 Then Exit FunctionCopyMemory mask(0), byt(4), 4ReDim bData(L + 4)        L = L + 1CopyMemory Lb(0), L, 4bData(0) = &H81        bData(1) = &H7E        bData(2) = Lb(1)        bData(3) = Lb(0)        inx = 8sti = 4ElseIf L = 127 ThenIf UBound(byt) <> L + 9 Then Exit FunctionLb(0) = byt(5)        Lb(1) = byt(4)        Lb(2) = byt(3)        Lb(3) = byt(2)        CopyMemory L, Lb(0), 4CopyMemory mask(0), byt(6), 4inx = 10sti = 6L = 0 '由于本次应用不处理长帧,所以设为0End IfIf L <= 0 Then Exit FunctionFor i = inx To UBound(byt)        bData(sti) = byt(i) Xor mask((i - inx) Mod 4)        sti = sti + 1Next i'========================================================='Debug'========================================================='    s = "Pick[" & UBound(bData) + 1 & "]" & vbCrLf'    For i = 0 To UBound(bData)'        s = s & bData(i) & " "'    Next i'    s = s & vbCrLf & "Scor[" & UBound(byt) + 1 & "]" & vbCrLf'    For i = 0 To UBound(byt)'        s = s & byt(i) & " "'    Next i'    Showlog s'=========================================================byt = bData    PickData = TrueEnd Function


SHA1加密,算法来源于网络上做了一些修改:

Option ExplicitPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal length As Long)' TITLE:' Secure Hash Algorithm, SHA-1' AUTHORS:' Adapted by Iain Buchan from Visual Basic code posted at Planet-Source-Code by Peter Girard' http://www.planetsourcecode.com/xq/ASP/txtCodeId.13565/lngWId.1/qx/vb/scripts/ShowCode.htm' PURPOSE:' Creating a secure identifier from person-identifiable data' The function SecureHash generates a 160-bit (20-hex-digit) message digest for a given message (String).' It is computationally infeasable to recover the message from the digest.' The digest is unique to the message within the realms of practical probability.' The only way to find the source message for a digest is by hashing all possible messages and comparison of their digests.' REFERENCES:' For a fuller description see FIPS Publication 180-1:' http://www.itl.nist.gov/fipspubs/fip180-1.htm' SAMPLE:' Message: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"' Returns Digest: "84983E441C3BD26EBAAE4AA1F95129E5E54670F1"' Message: "abc"' Returns Digest: "A9993E364706816ABA3E25717850C26C9CD0D89D"Private Type WordB0 As ByteB1 As ByteB2 As ByteB3 As ByteEnd Type'Public Function idcode(cr As Range) As String' Dim tx As String' Dim ob As Object' For Each ob In cr' tx = tx & LCase(CStr(ob.Value2))' Next' idcode = sha1(tx)'End FunctionPrivate Function AndW(w1 As Word, w2 As Word) As WordAndW.B0 = w1.B0 And w2.B0AndW.B1 = w1.B1 And w2.B1AndW.B2 = w1.B2 And w2.B2AndW.B3 = w1.B3 And w2.B3End FunctionPrivate Function OrW(w1 As Word, w2 As Word) As WordOrW.B0 = w1.B0 Or w2.B0OrW.B1 = w1.B1 Or w2.B1OrW.B2 = w1.B2 Or w2.B2OrW.B3 = w1.B3 Or w2.B3End FunctionPrivate Function XorW(w1 As Word, w2 As Word) As WordXorW.B0 = w1.B0 Xor w2.B0XorW.B1 = w1.B1 Xor w2.B1XorW.B2 = w1.B2 Xor w2.B2XorW.B3 = w1.B3 Xor w2.B3End FunctionPrivate Function NotW(w As Word) As WordNotW.B0 = Not w.B0NotW.B1 = Not w.B1NotW.B2 = Not w.B2NotW.B3 = Not w.B3End FunctionPrivate Function AddW(w1 As Word, w2 As Word) As WordDim i As Long, w As Wordi = CLng(w1.B3) + w2.B3w.B3 = i Mod 256i = CLng(w1.B2) + w2.B2 + (i \ 256)w.B2 = i Mod 256i = CLng(w1.B1) + w2.B1 + (i \ 256)w.B1 = i Mod 256i = CLng(w1.B0) + w2.B0 + (i \ 256)w.B0 = i Mod 256AddW = wEnd FunctionPrivate Function CircShiftLeftW(w As Word, n As Long) As WordDim d1 As Double, d2 As Doubled1 = WordToDouble(w)d2 = d1d1 = d1 * (2 ^ n)d2 = d2 / (2 ^ (32 - n))CircShiftLeftW = OrW(DoubleToWord(d1), DoubleToWord(d2))End FunctionPrivate Function WordToHex(w As Word) As StringWordToHex = Right$("0" & Hex$(w.B0), 2) & Right$("0" & Hex$(w.B1), 2) _& Right$("0" & Hex$(w.B2), 2) & Right$("0" & Hex$(w.B3), 2)End FunctionPrivate Function HexToWord(H As String) As WordHexToWord = DoubleToWord(Val("&H" & H & "#"))End FunctionPrivate Function DoubleToWord(n As Double) As WordDoubleToWord.B0 = Int(DMod(n, 2 ^ 32) / (2 ^ 24))DoubleToWord.B1 = Int(DMod(n, 2 ^ 24) / (2 ^ 16))DoubleToWord.B2 = Int(DMod(n, 2 ^ 16) / (2 ^ 8))DoubleToWord.B3 = Int(DMod(n, 2 ^ 8))End FunctionPrivate Function WordToDouble(w As Word) As DoubleWordToDouble = (w.B0 * (2 ^ 24)) + (w.B1 * (2 ^ 16)) + (w.B2 * (2 ^ 8)) _+ w.B3End FunctionPrivate Function DMod(value As Double, divisor As Double) As DoubleDMod = value - (Int(value / divisor) * divisor)If DMod < 0 Then DMod = DMod + divisorEnd FunctionPrivate Function F(t As Long, b As Word, C As Word, D As Word) As WordSelect Case tCase Is <= 19F = OrW(AndW(b, C), AndW(NotW(b), D))Case Is <= 39F = XorW(XorW(b, C), D)Case Is <= 59F = OrW(OrW(AndW(b, C), AndW(b, D)), AndW(C, D))Case ElseF = XorW(XorW(b, C), D)End SelectEnd FunctionPublic Function StringSHA1(inMessage As String) As String' 计算字符串的SHA1摘要Dim inLen As LongDim inLenW As WordDim padMessage As StringDim numBlocks As LongDim w(0 To 79) As WordDim blockText As StringDim wordText As StringDim i As Long, t As LongDim temp As WordDim k(0 To 3) As WordDim H0 As WordDim H1 As WordDim H2 As WordDim H3 As WordDim H4 As WordDim A As WordDim b As WordDim C As WordDim D As WordDim E As WordinMessage = StrConv(inMessage, vbFromUnicode)inLen = LenB(inMessage)inLenW = DoubleToWord(CDbl(inLen) * 8)padMessage = inMessage & ChrB(128) _& StrConv(String((128 - (inLen Mod 64) - 9) Mod 64 + 4, Chr(0)), 128) _& ChrB(inLenW.B0) & ChrB(inLenW.B1) & ChrB(inLenW.B2) & ChrB(inLenW.B3)numBlocks = LenB(padMessage) / 64' initialize constantsk(0) = HexToWord("5A827999")k(1) = HexToWord("6ED9EBA1")k(2) = HexToWord("8F1BBCDC")k(3) = HexToWord("CA62C1D6")' initialize 160-bit (5 words) bufferH0 = HexToWord("67452301")H1 = HexToWord("EFCDAB89")H2 = HexToWord("98BADCFE")H3 = HexToWord("10325476")H4 = HexToWord("C3D2E1F0")' each 512 byte message block consists of 16 words (W) but W is expandedFor i = 0 To numBlocks - 1blockText = MidB$(padMessage, (i * 64) + 1, 64)' initialize a message blockFor t = 0 To 15wordText = MidB$(blockText, (t * 4) + 1, 4)w(t).B0 = AscB(MidB$(wordText, 1, 1))w(t).B1 = AscB(MidB$(wordText, 2, 1))w(t).B2 = AscB(MidB$(wordText, 3, 1))w(t).B3 = AscB(MidB$(wordText, 4, 1))Next' create extra words from the message blockFor t = 16 To 79' W(t) = S^1 (W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16))w(t) = CircShiftLeftW(XorW(XorW(XorW(w(t - 3), w(t - 8)), _w(t - 14)), w(t - 16)), 1)Next' make initial assignments to the bufferA = H0b = H1C = H2D = H3E = H4' process the blockFor t = 0 To 79temp = AddW(AddW(AddW(AddW(CircShiftLeftW(A, 5), _F(t, b, C, D)), E), w(t)), k(t \ 20))E = DD = CC = CircShiftLeftW(b, 30)b = AA = tempNextH0 = AddW(H0, A)H1 = AddW(H1, b)H2 = AddW(H2, C)H3 = AddW(H3, D)H4 = AddW(H4, E)NextStringSHA1 = WordToHex(H0) & WordToHex(H1) & WordToHex(H2) _& WordToHex(H3) & WordToHex(H4)End FunctionPublic Function SHA1(inMessage() As Byte) As Byte()' 计算字节数组的SHA1摘要Dim inLen As LongDim inLenW As WordDim numBlocks As LongDim w(0 To 79) As WordDim blockText As StringDim wordText As StringDim t As LongDim temp As WordDim k(0 To 3) As WordDim H0 As WordDim H1 As WordDim H2 As WordDim H3 As WordDim H4 As WordDim A As WordDim b As WordDim C As WordDim D As WordDim E As WordDim i As LongDim lngPos As LongDim lngPadMessageLen As LongDim padMessage() As ByteinLen = UBound(inMessage) + 1inLenW = DoubleToWord(CDbl(inLen) * 8)lngPadMessageLen = inLen + 1 + (128 - (inLen Mod 64) - 9) Mod 64 + 8ReDim padMessage(lngPadMessageLen - 1) As ByteFor i = 0 To inLen - 1padMessage(i) = inMessage(i)Next ipadMessage(inLen) = 128padMessage(lngPadMessageLen - 4) = inLenW.B0padMessage(lngPadMessageLen - 3) = inLenW.B1padMessage(lngPadMessageLen - 2) = inLenW.B2padMessage(lngPadMessageLen - 1) = inLenW.B3numBlocks = lngPadMessageLen / 64' initialize constantsk(0) = HexToWord("5A827999")k(1) = HexToWord("6ED9EBA1")k(2) = HexToWord("8F1BBCDC")k(3) = HexToWord("CA62C1D6")' initialize 160-bit (5 words) bufferH0 = HexToWord("67452301")H1 = HexToWord("EFCDAB89")H2 = HexToWord("98BADCFE")H3 = HexToWord("10325476")H4 = HexToWord("C3D2E1F0")' each 512 byte message block consists of 16 words (W) but W is expanded' to 80 wordsFor i = 0 To numBlocks - 1' initialize a message blockFor t = 0 To 15w(t).B0 = padMessage(lngPos)w(t).B1 = padMessage(lngPos + 1)w(t).B2 = padMessage(lngPos + 2)w(t).B3 = padMessage(lngPos + 3)lngPos = lngPos + 4Next' create extra words from the message blockFor t = 16 To 79' W(t) = S^1 (W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16))w(t) = CircShiftLeftW(XorW(XorW(XorW(w(t - 3), w(t - 8)), _w(t - 14)), w(t - 16)), 1)Next' make initial assignments to the bufferA = H0b = H1C = H2D = H3E = H4' process the blockFor t = 0 To 79temp = AddW(AddW(AddW(AddW(CircShiftLeftW(A, 5), _F(t, b, C, D)), E), w(t)), k(t \ 20))E = DD = CC = CircShiftLeftW(b, 30)b = AA = tempNextH0 = AddW(H0, A)H1 = AddW(H1, b)H2 = AddW(H2, C)H3 = AddW(H3, D)H4 = AddW(H4, E)NextDim byt(19) As ByteCopyMemory byt(0), H0, 4CopyMemory byt(4), H1, 4CopyMemory byt(8), H2, 4CopyMemory byt(12), H3, 4CopyMemory byt(16), H4, 4SHA1 = bytEnd Function

BASE64编码:

Function Base64EncodeEX(Str() As Byte) As StringOn Error GoTo overDim buf() As Byte, length As Long, mods As LongConst B64_CHAR_DICT = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="mods = (UBound(Str) + 1) Mod 3length = UBound(Str) + 1 - modsReDim buf(length / 3 * 4 + IIf(mods <> 0, 4, 0) - 1)Dim i As LongFor i = 0 To length - 1 Step 3buf(i / 3 * 4) = (Str(i) And &HFC) / &H4        buf(i / 3 * 4 + 1) = (Str(i) And &H3) * &H10 + (Str(i + 1) And &HF0) / &H10        buf(i / 3 * 4 + 2) = (Str(i + 1) And &HF) * &H4 + (Str(i + 2) And &HC0) / &H40        buf(i / 3 * 4 + 3) = Str(i + 2) And &H3FNextIf mods = 1 Thenbuf(length / 3 * 4) = (Str(length) And &HFC) / &H4        buf(length / 3 * 4 + 1) = (Str(length) And &H3) * &H10        buf(length / 3 * 4 + 2) = 64buf(length / 3 * 4 + 3) = 64ElseIf mods = 2 Thenbuf(length / 3 * 4) = (Str(length) And &HFC) / &H4        buf(length / 3 * 4 + 1) = (Str(length) And &H3) * &H10 + (Str(length + 1) And &HF0) / &H10        buf(length / 3 * 4 + 2) = (Str(length + 1) And &HF) * &H4        buf(length / 3 * 4 + 3) = 64End IfFor i = 0 To UBound(buf)        Base64EncodeEX = Base64EncodeEX + Mid(B64_CHAR_DICT, buf(i) + 1, 1)Nextover:End Function

很多人卡在计算key上,需要调用上面的sha1加密和base64编码函数:

Private Function AcceptKey(k As String) As StringDim b() As Byteb = SHA1(StrConv(k & "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", vbFromUnicode))    AcceptKey = Base64EncodeEX(b)End Function

剩下应该就没多少问题了...

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Excel之VBA常用功能应用篇:VBA定义字节数据类型的应用方法
SM2签名的预处理过程
用VB读取unicode 编码的中英文字符混合的文本文件,中文显示乱码怎么解决?
VB.NET 对字符串进行加密和解密的方法
三类加密算法VB.NET的实现
java 输入流转字节数组
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服