2012-02-22 48 views
1

目前,客戶端發送的消息是這樣的:更好的socket通信系統

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 

所以它所做的就是將收到的信息和spli將其轉換爲使用-MSGDelimit-作爲分隔符的數組。所以在這種情況下,CompareFileMD5()函數將收到12,54,filename.txt,*md5hash*。並基於它可以返回到客戶端,無論MD5是否匹配。

當然,它工作,但它感覺sl and,服務器上的代碼變得非常混亂。

這裏的相關性較低的功能,從上面的代碼(懷疑的問題,但你永遠不知道):

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 

那麼,該如何處理的更好/清潔/更專業的建議嗎?

回答

0

根據不同的應用,您當前的解決方案可能會非常好。有一些事情可以脫穎而出:

  • 「協議」在數據發送量方面有點重。數據段之間的分隔符增加了相當多的開銷。在這個例子中,它可能佔有效載荷的50%。另外,將所有數據作爲文本發送可能使得有效載荷大於絕對必要的。但是,所有這些都不一定是問題。如果客戶端和服務器之間的流量相對較小,那麼線路上的額外數據可能根本就不成問題。對於這種大小的請求(有或沒有相對高的分隔符開銷),主要開銷將是往返開銷成本,並且通過將該分組的大小減小一半可能變化很小。但是,如果有數千條數據請求,那麼減少有效負載大小將會有所幫助。

  • 根據發送的數據,使用所示的分隔符可能是不明確的。考慮到分隔符的長度和格式是不太可能的,但是如果存在將「看起來」像分隔符的實際數據存在的可能性,則需要記住這一點。

假設所示的例子是許多類似協議之一,我會傾向於採取不同的路線。一種可能性是將請求捆綁爲JSON對象。現有的軟件包可用於創建和讀取JSON。一個例子是Json.NET。 JSON具有明確的結構,人類很容易閱讀和驗證,並且可以輕鬆擴展。根據您發送的數據,它可能會比當前的格式輕一些。 (也許你感興趣的部分),它可能會更「專業」。

了一些額外的事情,我會做(個人意見):

  • 可能添加客戶端版本被髮送的數據,這樣服務器就會知道,如果它「承認」的要求。以某個值開始客戶端版本(例如,1)。如果協議格式有更新(例如,不同的數據,不同的結構),則在該版本的軟件中將版本更改爲2。然後服務器可以查看版本號,看它是否識別它。如果它是服務器的第一個版本並且看到版本2,則它可以返回一個錯誤,指示服務器需要更新。如果您可以保證客戶端和服務器版本始終匹配,則這不是必需的(有時這在實踐中很難實現)。
  • 對請求類型使用整數值而不是字符串('checkFileMD5')。如果將要有大量的請求類型,服務器可以基於整數值更有效地(可能)分派請求。
+0

感謝您的回覆,您能否詳細說明''可能是發送數據的客戶端版本'',因爲我不明白這句話。目前JSON看起來相當不錯。 – natli 2012-02-22 16:22:51

+0

@natli:對不起,這並沒有幫助我在句子中留下了一個字。我編輯並添加了澄清信息。 – 2012-02-22 16:30:19

+0

啊,現在有道理!非常感謝,看起來我有一些工作要做;) – natli 2012-02-22 16:39:19