5

लिख नहीं सकता है मैं वर्तमान में एक जावा प्रोग्राम लिख रहा हूं जो क्रोम एक्सटेंशन के साथ संचार करता है। संवाद करने के लिए मुझे क्रोम मूल संदेश प्रोटोकॉल को लागू करने की आवश्यकता है। Google क्रोम दस्तावेज़ कहते हैं:क्रोम एक्सटेंशन के साथ जावा मूल संदेश - सही ढंग से लंबाई

... प्रत्येक संदेश JSON, UTF-8 एन्कोडेड का उपयोग करके क्रमबद्ध किया गया है और मूल बाइट ऑर्डर में 32-बिट संदेश लंबाई से पहले है। (Source)

मैंने जावा में इसे कार्यान्वित करने का प्रयास किया, लेकिन मेरे संदेशों में एक निश्चित लंबाई होने पर मुझे समस्याएं हैं, भले ही मेरा कार्यान्वयन सही होना चाहिए।

// read the message size from Chrome. This part works correctly. 
public static int getInt(char[] bytes) { 
    return (bytes[3]<<24) & 0xff000000| 
      (bytes[2]<<16) & 0x00ff0000| 
      (bytes[1]<< 8) & 0x0000ff00| 
      (bytes[0]<< 0) & 0x000000ff; 
} 

// transform the length into the 32-bit message length. 
// This part works for small numbers, but does not work for length 2269 for example. 
public static String getBytes(int length) { 
    return String.format("%c%c%c%c", 
      (char) (length  & 0xFF), 
      (char) ((length>>8) & 0xFF), 
      (char) ((length>>16) & 0xFF), 
      (char) ((length>>24) & 0xFF)); 
} 

ऐसा लगता है समस्या रास्ता जावा वर्ण को लागू करता है में निहित है: यहाँ मेरी वर्तमान कार्यान्वयन, के आधार पर पहले & सवाल (here उदाहरण के लिए) SO-उत्तर देता है। मैं सामान्य वर्णों की अपेक्षा करता हूं, जैसे कि सी में। प्रैक्टिस में, ऐसा लगता है कि जावा कभी-कभी इन वर्णों को यूनिकोड-वर्णों में बदल देता है (या कम से कम, यह अब तक मेरा संदेह है)।

0000000: c39d 0800 00        ..... 

उम्मीद उत्पादन तथापि (अजगर के साथ): यह निम्न उत्पादन में परिलक्षित होता है लंबाई 2269 के लिए जावा-कार्यक्रम से (वास्तविक बाइट्स को दिखाने के लिए XXD को पहुंचाया)

import struct 
struct.pack('I', 2269) 
# outputs in interactive mode: '\xdd\x08\x00\x00' 

क्या बिल्कुल यहाँ हो रहा है? जावा मेरे "0xDD" को "0xC39D" में क्यों परिवर्तित करता है और क्रोम मूल संदेश के लिए अपेक्षित इनपुट का प्रतिनिधित्व करने के लिए मैं अपना getBytes फ़ंक्शन कैसे प्राप्त कर सकता हूं? दूसरी भाषा का उपयोग करना एक विकल्प नहीं है।

उत्तर

4

जावा में वर्ण स्वचालित रूप से यूनिकोड में परिवर्तित हो जाते हैं। इस उपयोग के मामले के लिए सही प्रकार byte है, जो स्वचालित रूप से परिवर्तित नहीं होता है और सही मान रखता है। क्रोम स्थानीय संदेश प्रोटोकॉल का सही कार्यान्वयन इस प्रकार इस प्रकार है:

public static byte[] getBytes(int length) { 
     byte[] bytes = new byte[4]; 
     bytes[0] = (byte) (length  & 0xFF); 
     bytes[1] = (byte) ((length>>8) & 0xFF); 
     bytes[2] = (byte) ((length>>16) & 0xFF); 
     bytes[3] = (byte) ((length>>24) & 0xFF); 
     return bytes; 
    } 

इस विधि इसके अलावा, ध्यान लंबाई-बाइट और उत्पादन की गणना के बीच कहीं भी एक स्ट्रिंग का उपयोग करने के लिए नहीं किया जाना चाहिए। System.out आउटपुट निम्नलिखित के रूप में किया जा सकता है:

try { 
     System.out.write(getBytes(message.length())); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } 
+0

मैं तुम्हें जवाब देने के लिए प्रयोग किया जाता है, लेकिन यह विस्तार पक्ष में यह त्रुटि प्राप्त काम नहीं किया: मूल आवेदन 977,472,013 बाइट्स की संदेश, जिनमें से सीमा से अधिक भेजने की कोशिश की 1048576 बाइट्स। – Leon

+0

अपने आवेदन को मैन्युअल रूप से चलाने और xxd के माध्यम से इसे पाइप करने का प्रयास करें। क्या गलत हो रहा है यह जानने के लिए आपको ट्रैक पर जाना चाहिए। संभावना है कि आप वास्तविक आउटपुट से पहले एक नई लाइन (\ r \ n) आउटपुट कर रहे हैं। 'struct.pack ('I', 977472013)' -> ''\ r \ nC:''। एक सही संदेश पहले लंबाई, और फिर वास्तविक सामग्री भेजता है। – Snicksie

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