2009-09-13 67 views
1

我正在通過TCP/IP連接傳遞XML字符串的C++客戶端/服務器項目。我的問題是關於指示已收到完整字符串的正確方法。我正在考慮空終止的字符串或首先發送XML字符串的長度,因此客戶端/服務器可以知道何時接收到完整的字符串。如何在自定義TCP客戶端/服務器之間正確傳遞XML字符串?

客戶端可以發送GET/SET命令,服務器可以回覆,併發送連續的結果流。例如:客戶端發送<GET ID="DATA1" />和服務器回覆<ID="DATA1" VAL="..." />或服務器可以發送連續流:

​​

在這種情況下,客戶端可能會收到一個閱讀:

<ID="DATA1" VAL="..." /><ID="DATA2" VAL="..." />

或者,如果發送大量數據可能需要多次讀取才能讀取整個字符串。

使用空值終止字符似乎有點簡單化(和休息,如果字符串是unicode的?),併發送一個長度值似乎尷尬,以及:

20<ID="DATA1" VAL="1" /><length=20><ID="DATA1" VAL="1" />

這一定已經解決了TX /接收HTML文件,我似乎無法弄清楚。

我爲客戶端使用MFC C++(遺留代碼)服務器和.Net C++/CLI或C#。

任何幫助,非常感謝!

+0

退房http://www.jmarshall.com/easy/http/#structure ...空行(CRLF序列)在HTTP常見的分隔符。我確實希望你在服務器上使用某種XML框架,而不是僅僅將字符串混合在一起來創建XML。但是,如果你是這樣的話,記得要正確地對XML進行編碼,所以如果你發送了一堆帶有段落的文本,它並不會破壞你的協議。 – overslacked 2009-09-13 20:59:14

+0

感謝您的所有答案!所有好主意,我喜歡簡單CRLF分隔的想法,似乎最簡單。從提供的鏈接將這項工作? (帶CRLF ==兩個字節1013) 發送: CRLF 回覆 CRLF CRLF CRLF ... 如下面的答案2所示,可能會出現多行XML回覆。這可能會導致每條線路的CRLF出現問題,而不是響應的結束? 回覆 CRLF <數據ID = 「DATA1」/> CRLF <數據ID = 「DATA2」/> CRLF CRLF – Brian 2009-09-13 23:19:10

+0

對不起,我是新來的,那最後的評論沒有格式化好 - 我將作爲另一個答案 – Brian 2009-09-13 23:19:56

回答

0

使用零字節是正確的方法。它應該(至少afaik)在unicode或其他編碼方面不會破壞任何東西,並且給你絕對比任何長度的字節/長度更大的靈活性。

5

你的例子實際上並不是格式良好的XML,它可能是你問題的一部分。如果你打算使用XML的麻煩,你不妨使用格式良好的XML,它有規則節點終止,即:

<data id="DATA1" val="..." /> 

然後,您可以使用一個SAX解析器的流,它會給你的事件作爲節點和屬性被解析。

話,我會實現你的兩種類型的命令是這樣的:

// individual commands 
<get id="data_1"/> 

// multiple commands 
<multi> 
    <data id="DATA1"/> 
    <data id="DATA2"/> 
    ... 
</multi> 
+0

+1再次發佈,但要迂腐,你應該寫下「格式良好的XML」。 「有效的XML」意味着XML符合模式,這是非常不同的:http://en.wikipedia.org/wiki/XML#Well-formedness_and_error-handling – 2009-09-13 22:38:11

+0

好點 - 我會改變它。 – 2009-09-14 02:01:55

+0

我同意這一點 - 最合乎邏輯的方法是擴展你的XML模式,這樣一個完整的請求由''和'' 。 – caf 2009-09-16 05:55:17

0

有三種方法我能想到的:

  • 描述長度帶外: 這可能是一個很像HTTP 標題:CR刪除ASCII中的長度,然後所有後續字節計入 長度。
  • Null終止字符串。空字符是獨特的。
  • CR或LF終止節點,並且基於行的協議可以讀取XML。

正如其他地方所提到的,確保您的XML符合標準,以便任何一方都可以被換出,然後舊代碼將不必調整以符合標準。

1

我看到兩個選項,使一個很大的意義,我已經使用前:

1-只要給它,不終止XML。如果XML有效,它將只有一個根節點。您不必終止它,因爲客戶端可以解析它,直到它發現它具有完整的XML文件。

2-使用「帕斯卡」風格的字符串。我覺得這很容易,因爲閱讀可以一次完成,並且使所有其餘的問題都不存在。基本上,用一個整數表示你的「字符串」文檔,該整數是要發送的字節數。我在處理TCP時特別這樣做,因爲我可以一次性提取所謂的「數據包」或完整數據組。

0

我喜歡簡單的CRLF分隔的想法,看起來最簡單。從提供的鏈接將這項工作? (帶CRLF ==兩個字節1013)

發送:

<GET ID="DATA1" />CRLF 

答覆:

<ID="DATA1" VAL="3" />CRLF 
    <ID="DATA1" VAL="2" />CRLF 
    <ID="DATA1" VAL="1" />CRLF 
    ... 

作爲答案2所提到的,可能會發生與多行的XML回覆。這可能會導致每條線路的CRLF出現問題,而不是響應的結束?無法在多行XML字符串中自然發生CRLF?

回覆:

<multi>CRLF 
    <data id="DATA1"/>CRLF 
    <data id="DATA2"/>CRLF 
    </multi>CRLF 
+0

好的,從XML規範看來,行結束只能是LF,並且如果找到CRLF或CR,它們將被轉換爲LF: http://www.w3.org/TR/REC-xml/# sec-line-ends 因此,使用CRLF作爲XML字符串數據包分隔符看起來應該起作用。我會嘗試一下。 感謝您的幫助。 – Brian 2009-09-14 16:15:48

相關問題