2012-10-28 15 views
5

मैंने जावा में एक क्लाइंट बनाया और मैं बस अपने सर्वर पर कुछ डेटा भेजना चाहता हूं जो सी # में है।क्लाइंट/सर्वर ऐप - बाइट्स

समस्या यह है कि यदि मैं क्लाइंट में उदाहरण के लिए लिखता हूं, तो मुझे केवल पहला अक्षर मिलता है। बाइट सरणी में केवल एक तत्व है।

मुझे लगता है कि सर्वर पक्ष में कुछ समस्या है क्योंकि जावा में मेरे सर्वर में सब कुछ ठीक काम करता है ताकि क्लावा में क्लाइंट ठीक काम करता है।

क्या कोई भी कोई समस्या देखता है?

अग्रिम धन्यवाद।

+1

क्या आपने यह पता लगाने के लिए डीबग किया था कि क्या है> 1? –

+0

के = 1. यदि मैं इसे अच्छी तरह से प्राप्त करता हूं, तो यह होना चाहिए कि बाइट सरणी में कितने तत्व हैं। लेकिन चूंकि केवल एक तत्व है, के = 1. – Kubik

+0

डेटा भेजने के बाद आउटपुटस्ट्रीम को फ़्लश करने का प्रयास करें। –

उत्तर

2

समस्या जावा पक्ष में संभवतः है क्योंकि आपका श्रोता ठीक काम करता है। मैंने प्रतिलिपि आपके श्रोता कोड को टेस्ट एप्लिकेशन में चिपकाया है। मैंने एक और परीक्षण आवेदन बनाया और हैलो शब्द भेज दिया और मैंने इसे पूरी तरह से सुना।

public static void sender() 
{ 
    TcpClient client = new TcpClient(); 
    IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("192.168.2.236"), 30000); 
    client.Connect(serverEndPoint); 
    NetworkStream clientStream = client.GetStream(); 
    ASCIIEncoding encoder = new ASCIIEncoding(); 
    byte[] buffer = encoder.GetBytes("Hello Server!"); 

    clientStream.Write(buffer, 0, buffer.Length); 
    clientStream.Flush(); 
} 


Connection accepted from 192.168.2.236:22811 
Recieved... 
Hello Server! 

Btw, इस बेहतर श्रोता हो सकता है।

public void listener() 
    { 
    TcpListener tcpListener = new TcpListener(IPAddress.Any, 30000); 
    tcpListener.Start(); 

    TcpClient tcpClient = tcpListener.AcceptTcpClient(); 
    NetworkStream clientStream = tcpClient.GetStream(); 

    byte[] message = new byte[4096]; 
    int bytesRead; 

    while (true) 
    { 
    bytesRead = 0; 

    try 
    { 
     //blocks until a client sends a message 
     bytesRead = clientStream.Read(message, 0, 4096); 
    } 
    catch 
    { 
     //a socket error has occured 
     break; 
    } 

    if (bytesRead == 0) 
    { 
     //the client has disconnected from the server 
     break; 
    } 

    //message has successfully been received 
    ASCIIEncoding encoder = new ASCIIEncoding(); 
    Console.Write(encoder.GetString(message, 0, bytesRead)); 
    } 

    tcpClient.Close(); 
} 
+0

धन्यवाद! यह श्रोता काम करता है। यहां तक ​​कि अगर मैं अभी भी नहीं मिला कि पिछला एक क्यों नहीं था। – Kubik

3

आप गलत तरीके से टीसीपी के बारे में सोच रहे हैं, आप बस एक बार "प्राप्त" नहीं करते हैं और एक "भेजें" का परिणाम प्राप्त नहीं करते हैं।

टीसीपी एक "स्ट्रीमिंग" प्रोटोकॉल है और स्वचालित रूप से "पैकेट" में अलग नहीं होता है। आप एक प्राप्त में 2 भेज सकते हैं डेटा भी प्राप्त कर सकते हैं।

एक सामान्य पैटर्न एक संदेश को इसकी लंबाई के साथ उपसर्ग करना है, ताकि जब तक आपको अनुरोध किए गए बाइट्स की मात्रा प्राप्त न हो जाए तब तक आप कॉल प्राप्त कर सकते हैं। यदि बफर में कोई डेटा नहीं है, तो set your socket to non-blocking कोई डेटा तुरंत प्राप्त करने के लिए। क्योंकि स्थानीय नेटवर्क पर कोई विलंबता के बगल में है वहाँ

Here's another good article on the topic.

अब, अपनी प्रदान की कोड किसी भी तरह से काम करना चाहिए। क्या आपने जांच की है कि क्या आपका जावा भाग भाप भाप/क्या आप उन्हें मैन्युअल रूप से फ्लश कर सकते हैं?

3

के रूप में डैमन Gant कहा, टीसीपी एक स्ट्रीमिंग प्रोटोकॉल है। मेरा सुझाव है कि आप अपना खुद का प्रोटोकॉल बनाएं। मैं तार नहीं भेजूंगा। यदि आप कुछ भी गैर-तुच्छ कर रहे हैं तो यह वास्तव में जाने का सबसे अच्छा तरीका है।

आमतौर पर मैं एक जादू संख्या, चेकसम, बाइट में पैकेट शरीर की लंबाई, और प्रोटोकॉल हेडर में प्रोटोकॉल संस्करण शामिल करता हूं। जादू संख्या एक स्ट्रीम में पैकेट को चित्रित करना आसान बनाता है (आपके कस्टम प्रोटोकॉल स्ट्रीम को डीबग करने के लिए बहुत उपयोगी है।) चेकसम होने से यह सुनिश्चित करने में मदद मिलती है कि आप चीजों को सही तरीके से पार्स कर रहे हैं। एक चेकसम टीसीपी पर अखंडता के साथ ज्यादा मदद नहीं करता क्योंकि टीसीपी प्रोटोकॉल में पहले से ही एक चेकसम है। आपके पैकेट के लिए सभी बाइट्स होने पर पैकेट बॉडी की लंबाई आपको पता लगाने में सहायता करती है। प्रोटोकॉल संस्करण आपको पैकेट बॉडी के बाइट्स को समझने के तरीके के बारे में जानने में मदद कर सकता है।

डेटा प्राप्त करने पर, सभी बाइट्स को एक अलग बफर में रखें और अपने प्रोटोकॉल हेडर के लिए स्कैन करें। यदि आप अपने हेडर को पार्स कर सकते हैं, तो यह देखने के लिए जांचें कि पैकेट के बाइट सभी मौजूद हैं। यदि हां, तो पैकेट को पार्स करें। इस प्रक्रिया को तब तक दोहराएं जब तक आप एक अपूर्ण पैकेट नहीं पाते हैं, या बफर खाली होता है।

प्रत्येक पैकेट के लिए आप भेजना चाहते हैं, मैं एक कक्षा बनाउंगा। जब आप एक पैकेट भेजना चाहते हैं, उचित वर्ग बनाएं और क्रमबद्ध करें, और उस वर्ग के बाइट्स के लिए अपने प्रोटोकॉल हेडर को प्रीपेड करें।

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

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