Лучшая сокетная система связи - PullRequest
1 голос
/ 22 февраля 2012

В настоящее время клиент отправляет такие сообщения:

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 голосов
/ 22 февраля 2012

В зависимости от приложения, ваше текущее решение может быть в полном порядке. Есть пара вещей, которые немного выделяются:

  • «Протокол» немного тяжел с точки зрения количества отправляемых данных. Разделители между частями данных добавляют немного накладных расходов. В данном примере это может составлять 50% полезной нагрузки. Кроме того, отправка всех данных в виде текста потенциально увеличивает полезную нагрузку, чем это абсолютно необходимо. Все это, однако, не обязательно является проблемой. Если трафик между клиентом и сервером относительно невелик, то дополнительные данные на проводе могут вообще не быть проблемой. Для запроса такого размера (с относительно высокими издержками на разделители или без них) основными затратами будут затраты в оба конца, и они, вероятно, очень мало изменятся при уменьшении размера этого пакета вдвое. Однако, если есть запросы с тысячами фрагментов данных, то уменьшение размера полезной информации поможет.

  • Использование разделителей, как показано, потенциально неоднозначно в зависимости от отправляемых данных. Маловероятно, учитывая длину и формат разделителей, но об этом следует помнить, если когда-либо существует возможность иметь фактические данные, которые «выглядят» как разделитель.

Предполагая, что показанный пример является одним из многих похожих протоколов, я был бы склонен пойти другим путем. Одной из возможностей будет объединение запроса в виде JSON-объекта . Существуют доступные пакеты для создания и чтения JSON. Одним из примеров является Json.NET . JSON имеет четко определенную структуру, его легко читать и проверять, и его можно легко расширить. И в зависимости от данных, которые вы отправляете, они могут быть немного более легкими, чем текущий формат. И (возможно, часть, которая вас интересует), это может показаться более «профессиональным».

Пара дополнительных вещей, которые я бы сделал (личное мнение):

  • Возможно, добавьте версию клиента к отправляемым данным, чтобы сервер знал, распознает ли он запрос. Запустите версию клиента с некоторого значения (например, 1). Если имеются обновления в формате протокола (например, другие данные, другая структура), измените версию на 2 в этом выпуске программного обеспечения. Затем сервер может посмотреть номер версии, чтобы узнать, распознает ли он его. Если это первая версия сервера и он видит версию 2, он может вернуть ошибку, указывающую на необходимость обновления сервера. В этом нет необходимости, если вы можете гарантировать, что выпуски клиента и сервера всегда совпадают (иногда на практике это сложно).
  • Используйте целочисленное значение для типа запроса вместо строки ('checkFileMD5'). Если будет большое количество типов запросов, сервер может отправить запрос немного более эффективно (возможно) на основе целочисленного значения.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...