更好的插座通信系统

时间:2012-02-22 15:10:11

标签: vb.net sockets

目前,客户端正在发送如下消息:

Public Function checkMD5(ByVal userID As Integer, ByVal gameID As Integer, ByVal file As String, ByVal fileFull As String) As String
    Dim make As New CMakeMSG
    Dim md5 As New CMD5
    make.append("checkfileMD5")
    make.append(userID)
    make.append(containerID)
    make.append(file)
    make.append(md5.GenerateFileHash(fileFull))

    Return SocketSendAndReceiveMSG(make.makestring)
End Function

服务器可能会收到以下内容:

checkfileMD5-MSGDelimit0-12-MSGDelimit1-54-MSGDelimit2-filename.txt-MSGDelimit3-*md5hash*

然后它会读出来:

Private _message As String
Public Function handleMessage() As String
    Dim brokenMessage As New ArrayList
    brokenMessage = breakDown() 'Split to ArrayList

        If brokenMessage(0) = "checkfileMD5" Then
            Try
                If brokenMessage.Count > 5 Then
                    Return "0-structureMessedUp"
                End If
                Return CompareFileMD5(brokenMessage(1), brokenMessage(2), brokenMessage(3), brokenMessage(4))
            Catch ex As Exception
                Return "0-structureMessedUp"
            End Try
        End If
End Function

它的作用是接收消息,并使用-MSGDelimit-作为分隔符将其拆分为数组。因此,在这种情况下,CompareFileMD5()函数会收到12,54,filename.txt,*md5hash*。并且基于它可以返回到客户端,无论MD5是否匹配。

当然,它有效,但它感觉很草率,服务器上的代码变得非常混乱。

以上是与上述代码不太相关的功能(怀疑它很重要,但你永远不知道):

Private Function breakDown() As ArrayList
    Try
        Dim theArray As New ArrayList
        Dim copymsg As String = _message

        Dim counter As Integer = 0
        Do Until Not copymsg.Contains("-MSGDelimit")
            Dim found As String

            found = copymsg.Substring(0, copymsg.IndexOf("-MSGDelimit" & counter & "-"))

            theArray.Add(found)
            copymsg = copymsg.Replace(found & "-MSGDelimit" & counter & "-", "")

            counter += 1
        Loop

        theArray.Add(copymsg)
        Return theArray
    Catch ex As Exception
        Module1.msg(ex.Message)
    End Try
End Function

Private Function CompareFileMD5(ByVal userID As Integer, ByVal gameID As Integer, ByVal filename As String, ByVal source As String) As String
    Try
        Dim tryFindFile As String = Module1.filedatabase.findfile(userID, gameID, filename)

        If Not tryFindFile = "notFound" Then
            Dim fileFull As String = tryFindFile & "\" & filename
            Dim md5 As New CMD5
            If md5.GenerateFileHash(fileFull) = source Then
                Return "Match"
            Else
                Return "NoMatch"
            End If
        Else
            Return "notFound"
        End If
    Catch ex As Exception
        Module1.msg("0")
        Return "0"
    End Try
End Function

那么,关于如何更好地/更清洁/更专业地处理它的任何建议?

1 个答案:

答案 0 :(得分:0)

根据应用程序的不同,您当前的解决方案可能非常好。有几件事情确实很突出:

  • 就发送的数据量而言,“协议”有点重。数据片段之间的分隔符增加了相当多的开销。在该示例中,它占有效载荷的50%。此外,将所有数据作为文本发送可能会使有效负载大于绝对必要。但是,所有这些都不一定是个问题。如果客户端和服务器之间的流量相对较小,则线路上的额外数据可能根本不是问题。对于这种大小的请求(有或没有相对较高的分隔符开销),主要成本是往返成本,并且可能通过将该分组的大小减少一半而变化很小。但是,如果有数千条数据的请求,那么减少有效负载大小会有所帮助。

  • 根据发送的数据,所显示的分隔符的使用可能不明确。考虑到分隔符的长度和格式,这是不太可能的,但是如果有可能存在“看起来像分隔符”的实际数据,那就要记住了。

假设显示的示例是许多类似协议之一,我倾向于采用不同的路线。一种可能性是将请求捆绑为 JSON对象。现有的包可用于创建和读取JSON。一个例子是Json.NET。 JSON具有定义明确的结构,人们可以轻松阅读和验证,并且可以轻松扩展。根据您发送的数据,它可能比当前格式更轻量级。而且(也许你感兴趣的部分),它可能看起来更“专业”。

我会做的其他一些事情(个人意见):

  • 可能会向正在发送的数据添加客户端版本,以便服务器知道它是否“识别”了请求。以某个值(例如,1)启动客户端版本。如果存在协议格式的更新(例如,不同的数据,不同的结构),则在该软件版本中将版本更改为2。然后,服务器可以查看版本号以查看它是否识别它。如果它是服务器的第一个版本并且看到版本2,那么它可以返回错误,指示服务器需要更新。如果您可以保证客户端和服务器版本始终匹配(有时这在实践中很难),则没有必要这样做。
  • 对请求类型使用整数值而不是字符串('checkFileMD5')。如果将有大量请求类型,服务器可以基于整数值更有效地(可能)调度请求。