2008-09-18 9 views
7

से 4 बाइट संदेश शीर्षलेख भेजना मैं जावा में लिखे गए सर्वर पर सी # क्लाइंट लिखने की कोशिश कर रहा हूं। सर्वर को जावा में एक 4 बाइट (DataInputStread readInt() में उम्मीद है) संदेश संदेश हेडर वास्तविक संदेश के बाद।सी # क्लाइंट से जावा सर्वर

मैं सी # के लिए बिल्कुल नया हूं, मैं इस संदेश हेडर को जावा सर्वर पर कैसे भेज सकता हूं? मैंने इसे कई तरीकों से आजमाया (ज्यादातर सी # भाषा में बहुत गहराई से परीक्षण और त्रुटि), और कुछ भी काम नहीं किया। जावा पक्ष गलत (बहुत बड़ी) संदेश लंबाई के साथ समाप्त हुआ।

उत्तर

2

यह आसान है, लेकिन क्या आपने अंतहीनता की जांच की है? यह आसानी से endianness आप में डेटा भेजा है और endianness आप में प्राप्त कर रहे हैं के बीच एक बेमेल हो सकता है

0

मैं जानता हूँ कि सी # न लेकिन आप सिर्फ इस के बराबर करने की जरूरत है:।

out.write((len >>> 24) & 0xFF); 
out.write((len >>> 16) & 0xFF); 
out.write((len >>> 8) & 0xFF); 
out.write((len >>> 0) & 0xFF); 
1

हैं आप बहुत सारे डेटा का आदान-प्रदान करने जा रहे हैं, मैं स्ट्रीम-रैपर को लागू करने (या ढूंढने) की सिफारिश करता हूं जो नेटवर्क-ऑर्डर में इन्ट्स लिख और पढ़ सकता है। endianness के रूप में अन्य पोस्टर ने बताया है,

using(Socket socket = ...){ 
    NetworkStream ns = new NetworkStream(socket);  
    ns.WriteByte((size>>24) & 0xFF); 
    ns.WriteByte((size>>16) & 0xFF); 
    ns.WriteByte((size>>8) & 0xFF); 
    ns.WriteByte(size  & 0xFF); 
    // write the actual message 
} 
11

यह है, नीचे: लेकिन क्या तुम सच में ही लंबाई लिखने की ज़रूरत है, तो कुछ इस तरह से करते हैं।

जावा DataInputStream डेटा को big-endian (नेटवर्क बाइट ऑर्डर) होने की अपेक्षा करता है। मोनो प्रलेखन (BinaryWriter जैसे समकक्षों के लिए) से निर्णय लेते हुए, सी # छोटे-एंडियन (Win32/x86 के लिए डिफ़ॉल्ट) होने की ओर जाता है।

इसलिए, जब आप मानक वर्ग पुस्तकालय का उपयोग बाइट्स के लिए 32 बिट पूर्णांक '1' को बदलने के लिए, वे भिन्न परिणाम:

:

//byte hex values 
Java: 00 00 00 01 
    C#: 01 00 00 00 

आप जिस तरह से आप सी # में ints बारे में बदल सकते हैं

private static void WriteInt(Stream stream, int n) { 
    for(int i=3; i>=0; i--) 
    { 
     int shift = i * 8; //bits to shift 
     byte b = (byte) (n >> shift); 
     stream.WriteByte(b); 
    } 
} 

संपादित करें:

ऐसा करने का एक सुरक्षित तरीका होगा:

private static void WriteToNetwork(System.IO.BinaryWriter stream, int n) { 
    n = System.Net.IPAddress.HostToNetworkOrder(n); 
    stream.Write(n); 
} 
2

जैसा कि यहां हर कोई पहले से ही इंगित कर चुका है, सी # आवेदन के कारण यह समस्या कम अंतराल क्रम में इन्ट्स भेज रही है जबकि जावा ऐप उन्हें नेटवर्क ऑर्डर (बड़े-एंडियन) में अपेक्षा करता है। हालांकि, सी # ऐप में बाइट्स को स्पष्ट रूप से पुनर्व्यवस्थित करने के बजाय, सही तरीका होस्ट से नेटवर्क ऑर्डर (एचटीओएनएस और पसंद) में कनवर्ट करने के लिए अंतर्निहित कार्यों पर भरोसा करना है - इस तरह आपका कोड चलने पर भी ठीक काम करना जारी रखेगा एक बड़ी एंडियन मशीन पर।

सामान्यतः, जब इस तरह के मुद्दों का निवारण करते हैं, तो मुझे नेटकैट या वायरसहार्क जैसे टूल का उपयोग करके सही ट्रैफ़िक (उदाहरण के लिए जावा में जावा से जावा) रिकॉर्ड करना उपयोगी लगता है, और उसके बाद यह गलत ट्रैफिक से तुलना करें कि यह कहां है गलत हो रहा। एक अतिरिक्त लाभ के रूप में, आप सर्वर में कब्जे वाले/पूर्ववर्ती अनुरोधों को इंजेक्ट करने के लिए नेटकैट का उपयोग भी कर सकते हैं या क्लाइंट में कैप्चर/प्रीकॉर्डर्ड प्रतिक्रियाओं को इंजेक्ट कर सकते हैं। उल्लेख नहीं है कि आप फ़ाइल में अनुरोध/प्रतिक्रियाओं को भी संशोधित कर सकते हैं और कोड को ठीक करने से पहले परिणामों का परीक्षण कर सकते हैं।

0

Sysetm.Net.IPAddress क्लास में दो स्थैतिक सहायक विधियां हैं: HostToNetworkOrder() और NetworkToHostOrder() जो आपके लिए रूपांतरण करते हैं। आप उचित मूल्य लिखने के लिए स्ट्रीम पर एक बाइनरीवाइटर के साथ इसका उपयोग कर सकते हैं:

using (Socket socket = new Socket()) 
using (NetworkStream stream = new NetworkStream(socket)) 
using (BinaryWriter writer = new BinaryWriter(stream)) 
{ 
    int myValue = 42; 
    writer.Write(IPAddress.HostToNetworkOrder(myValue)); 
} 
संबंधित मुद्दे