2012-12-12 14 views
5

मैं इंडी क्लाइंट का उपयोग कर रहा हूं संदेश भेजने के लिए सर्वर मुझे भेज रहा है (क्लाइंट)। यह एक बार में मेरे लिए 512 बाइट डेटा भेजता है। डेटा के यह 512 बाइट दो डेटाटाइप (शब्द और स्ट्रिंग) से बना है। उदाहरण के लिए, यह 2 बाइट्स का शब्द भेजता है, फिर फिर 2 बाइट्स का शब्द और फिर 50 बाइट्स का स्ट्रिंग और इसी तरह।डेल्फी में इंडी क्लाइंट का उपयोग कर सर्वर से सभी बाइट्स को कैसे पढ़ा जाए?

var BufferArray : Array[0..512] of Byte; 

if IdTCPClient1.IOHandler.InputBufferIsEmpty then 
begin 
     if IdTCPClient1.IOHandler.CheckForDataOnSource(1000) then 
     begin 
      Edit1.Text := idtcpclient1.IOHandler.ReadBytes(BufferArray ,512, true); 
     end; 
end; 

मैं लाइन Edit1.Text पर त्रुटि हो रही है:: मैं इस समस्या से निपटने के लिए निम्न कोड कोशिश कर रहा हूँ = idtcpclient1.IOHandler.ReadBytes (BufferArray, 512, सच); त्रुटि: वास्तविक और औपचारिक var पैरामीटर का प्रकार समान होना चाहिए।

क्या यह सही दृष्टिकोण है जिसका मैं उपयोग कर रहा हूं। मैं Edit1.Text पर पूरे 512 बाइट्स को स्टोर करना चाहता हूं और फिर वह डेटा जो मैं उस डेटा के साथ करना चाहता हूं। कृपया सर्वर से सभी 512 बाइट प्राप्त करने में मेरी सहायता करें।

अद्यतन: अदल-बदल कर दृष्टिकोण

मैं इस दृष्टिकोण का उपयोग कर रहा शब्द पढ़ने के लिए और स्ट्रिंग को महत्व देता है की तरह

स्ट्रिंग के लिए

WordArray : array[0..5] of word; 

if IdTCPClient1.IOHandler.InputBufferIsEmpty then 
begin 
     if IdTCPClient1.IOHandler.CheckForDataOnSource(1000) then 
     begin 
     i := 0; 
     while i < 6 do //Read all the words 
     begin 
      //Fill WORD data in array 
      WordArray[i] := (IdTCPClient1.Socket.ReadWord(True)); 
     end; 
     end; 
end; 

इसी दृष्टिकोण WordArray [i]: = (IdTCPClient1। Socket.ReadString (50));

ठीक काम कर रहा है, लेकिन मुझे लूप में सभी डेटा पढ़ने के दौरान कनेक्शन खोलना होगा। यदि कनेक्शन के बीच में, मैं सब कुछ खो देता हूं और सर्वर से फिर से पूरे पैकेज का अनुरोध करना पड़ता हूं।

+1

उपयोग के लिए 'BufferArray', अपने घोषणा करने के लिए' वर BufferArray बदलने एक गतिशील सरणी: TBytes; '। – TLama

+0

हां, वही किया। इसने काम कर दिया। धन्यवाद। अब मुझे और समस्याएं हैं। मैं इस बफरएरे के माध्यम से कैसे पुन: प्रयास कर सकता हूं? मैं इसे सब कुछ एक स्ट्रिंग सरणी में स्टोर करना चाहता हूं। –

+0

@TLama - मेरा प्रश्न अपडेट किया गया। क्या मेरा नया दृष्टिकोण सही है? –

उत्तर

1

जब तक आप दस्तावेज में जो लिखा है उसका सटीक वर्णन नहीं करते हैं, तब तक आपको जवाब देना मुश्किल है। अब तक हम जानते हैं कि आपका 512 बी पैकेट 6 शब्द और 10x50B तारों से होता है। तो,, बस बिंदु शुरू करने के रूप में इस ले जब तक आप हमें और अधिक बता:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    I: Integer; 
    Buffer: TBytes; 
    WordArray: array[0..5] of Word; 
    StringArray: array[0..9] of AnsiString; 
begin 
    if IdTCPClient1.IOHandler.InputBufferIsEmpty then 
    begin 
    if IdTCPClient1.IOHandler.CheckForDataOnSource(1000) then 
     IdTCPClient1.IOHandler.ReadBytes(Buffer, 512, False); 

    for I := 0 to High(WordArray) do 
    begin 
     WordRec(WordArray[I]).Hi := Buffer[I * 2]; 
     WordRec(WordArray[I]).Lo := Buffer[I * 2 + 1]; 
    end; 
    for I := 0 to High(StringArray) do 
     SetString(StringArray[I], PAnsiChar(@Buffer[I * 50 + 12]), 50); 

    // here you have the arrays prepared to be processed 
    end; 
end; 
+0

ठीक है, इसे आज़माएं। अगर यह काम करता है, तो मैं आपको एक बड़ा धन्यवाद दूंगा –

+0

मुझे उम्मीद नहीं है कि यह काम करेगा, शब्द भाग बाइट्स को बदल सकता है और स्ट्रिंग भाग से उम्मीद है कि आप एएनएसआई वर्ण प्राप्त कर रहे हैं, इसलिए दोनों एक अनुमान है। मुझे पता नहीं है कि तारों को आपके सर्वर द्वारा कैसे भेजा जाता है, अगर वे एएनएसआई, यूनिकोड हैं, तो उन्हें कैसे समाप्त किया जाता है (यह असामान्य कुछ हो सकता है, मुझे नहीं पता)। मैं यह भी नहीं जानता कि उन शब्दों को कैसे भेजा जाता है, जिसमें बाइट ऑर्डर। मुझे इन जानकारी को मुझे उसमें जवाब को परिशोधित करने के लिए जोड़ना होगा। – TLama

+0

यदि यह काम नहीं करेगा, तो मैं आपके साथ एक शब्द दस्तावेज़ साझा करूंगा जो पैकेट का सटीक प्रारूप दिखाता है। –

1

1: स्ट्रिंग का वर्णमाला क्या है? क्या यह 1-बाइट विंडोज़ -1251 है? या 2-बाइट यूनिकोड यूसीएस -2? या परिवर्तनीय लंबाई यूटीएफ -8 या यूटीएफ -16?

2: स्ट्रिंग की लंबाई क्या है? हमेशा 50? मैनुअल
1,1 http://www.indyproject.org/docsite/html/[email protected]@[email protected]
1,2 http://www.indyproject.org/docsite/html/[email protected] 1,3 http://docwiki.embarcadero.com/Libraries/XE2/en/System.SetString

  • सही रूप में प्रकार और पैरामीटर विवरण निम्नलिखित कोड बनाने पढ़ने

    1. :


      बफर पढ़ने।
      2.1 पढ़ना हैडर: यह

      var Word1, Word2: word; 
      
      Word1 := IOHandler.ReadSmallInt(false); 
      Word2 := IOHandler.ReadSmallInt(false); 
      
    2. एकल-बाइट स्ट्रिंग
      3.1 बफर
      3.2 पढ़ने स्ट्रिंग

      var Word1, Word2: word; Buffer: TIdBytes;  
      var s: RawByteString;  
      // or AnsiString; or maybe UTF8String; but probably not UnicodeString aka string 
      
      Word1 := IOHandler.ReadSmallInt(false); 
      Word2 := IOHandler.ReadSmallInt(false); 
      
      // You should check that you really received 50 bytes, 
      // then do something like that: 
      
      IOHandler.ReadBytes(Buffer, 50, false);  
      Assert(Length(Buffer)=50);  
      SetString (s, pointer(@Buffer[0]), 50);  
      
    3. को बफर परिवर्तित पढ़ने की तरह कुछ में परिणाम चाहिए जारी बाकी पढ़ने - आप केवल 512 बाइट्स पैकेट के 50 + 2 + 2 = 54 बाइट्स पढ़ते हैं - वहां अधिक डेटा होना चाहिए।

    512 = 54 * 9 + 26 - तो यह एक लूप की तरह दिख सकता है - और 26 बाइट पूंछ को हटा सकता है।

    var Word1, Word2: word; Buffer: TIdBytes;  
        var s: RawByteString;  
    
        for i := 1 to 9 do begin  
         Word1 := IOHandler.ReadSmallInt(false);  
         Word2 := IOHandler.ReadSmallInt(false); 
    
         IOHandler.ReadBytes(Buffer, 50, false);   
         Assert(Length(Buffer)=50);  
         SetString (s, pointer(@Buffer[0]), 50);  
    
         SomeOutputCollection.AppendNewElement(Word1, Word2, s); 
        end; 
        IOHandler.ReadBytes(Buffer, 512 - 9*(50+2+2), false); // discard the tail 
    
  • +0

    @TLama रीडस्ट्रिंग यूनिकोडस्ट्रिंग लौटाता है। टॉपिक स्टार्टर ने लगभग 50 बाइट्स को बताया। संभावित भ्रम है - और मैंने जवाब के शीर्षलेख में ध्यान दिया। लेकिन जहां तक ​​स्टार्टर मूल "50 बाइट्स" दावे रखता है - ऐसा लगता है कि यह मेरे लिए है। जब तक इंडी 'ReadAnsiString (कॉन्स कोडपेज: शब्द; कॉन्स लम्बाई: कार्डिनल) पेश करेगी;' विधि –

    +0

    हाँ, मुझे एहसास हुआ कि मैंने अपनी टिप्पणी हटा दी है ... इसके लिए खेद है। – TLama

    +0

    मुझे अपने आप को सही करने दें और मैं अपने 512 पैकेट को कैसे पार्स करना चाहता हूं, इस बारे में और विस्तार से बताएं। मेरे पास इस पैकेट का दस्तावेज है जो कहता है कि 2 बाइट्स के 6 शब्द होंगे और फिर 50 बाइट्स के तार होंगे। अब मुझे अलग-अलग शब्द सरणी में शब्दों को अलग करना होगा और विभिन्न स्ट्रिंग सरणी में स्ट्रिंग करना होगा। अब मैं इन चीजों को इस पैकेट से कैसे निकाला जा सकता हूं? –

    संबंधित मुद्दे