मेरे पास एक TCP कनेक्शन है, कौन सा क्लाइंट PHP है और सर्वर C# है

यह सॉकेट कनेक्शन एक छवि को socket सर्वर पर स्थानांतरित करता है, लेकिन

यादृच्छिक रूप से कभी-कभी स्थानांतरण दूषित हो जाता है [छवि hash अलग है]

PHP क्लाइंट

$file = file_get_contents('img.bmp');
socket_write($socket,$file.$cordinates); it sends //image + sme other data
$recv = socket_read ($socket, 500, PHP_BINARY_READ) // read the server response

यह स्ट्रीम हमेशा एक बिटमैप छवि + कुछ डेटा स्थानांतरित करती है।


सी#

 this.DataSocket = this.Listner.Accept();
int filelength = this.DataSocket.Receive(this.buffer, this.buffer.Length, SocketFlags.None)

मैंने जांच की कि एक ताजा ब्राउज़र [नया खोला गया] में यह कभी विफल नहीं हुआ। लेकिन जब मैं एक ही ब्राउज़र में इस बनाई गई सेवा का उपयोग कई बार बार-बार करता हूं तो इसका उद्देश्य विफल होना था।

जब मैं ब्राउज़र के भिन्न ब्राउज़र या नए उदाहरण से जांचता हूं तो यह पहले कुछ प्रयासों में कभी विफल नहीं होता।

मुझे लगा कि यह caching के साथ कुछ समस्या थी, लेकिन मैं headers का उपयोग करके caching को अक्षम कर देता हूं लेकिन वही समस्या मौजूद है

4
Sudantha 18 जुलाई 2011, 08:58
1
सी # इसमें कहां से संबंधित है? या नहीं? (मुझे आश्चर्य है कि समस्या सी # में स्ट्रीम रीडिंग कोड है; लोगों को अक्सर यह गलत लगता है)
 – 
Marc Gravell♦
18 जुलाई 2011, 09:28
क्या किसी भी संयोग से असफल छवि का आकार 500 बाइट्स से अधिक है? क्या आप टीसीपी या यूडीपी का उपयोग कर रहे हैं? यदि आप यूडीपी का उपयोग कर रहे हैं तो यह नेटवर्क की भीड़ के कारण हो सकता है जो केवल कुछ अनुरोधों के बाद उत्पन्न होता है - और क्योंकि एचटीटीपी यानी टीसीपी उसी तार पर यूडीपी के रूप में यूडीपी पैकेट हानि के साथ कहर बरपाता है। क्या आपने इसे सरल बनाने के लिए अपने सी # ऐप में एचटीपी लिस्टनर का उपयोग करने पर विचार किया है?
 – 
Jonathan Dickinson
18 जुलाई 2011, 13:35
डिकिंसन वास्तव में नमूना डेटा जो मैंने उपयोग किया था वह 500Bytes से अधिक है, मुझे HttpListener की आपकी अवधारणा नहीं मिली है?
 – 
Sudantha
18 जुलाई 2011, 17:04
इसका हिसाब होगा, आप केवल पहले 500 बाइट प्राप्त कर रहे हैं। HttpListener के लिए, दस्तावेज़ीकरण पर एक नज़र डालें . इस तरह आप फ़ाइल प्राप्त करने के लिए केवल PHP HTTP विधियों का उपयोग कर सकते हैं। साथ ही, मैंने आपको जो लिंक दिया था, वह Google पर सबसे पहले परिणाम था।
 – 
Jonathan Dickinson
18 जुलाई 2011, 17:30

3 जवाब

सबसे बढ़िया उत्तर

आप एक बार में सॉकेट में पूरी फाइल लिखने की उम्मीद नहीं कर सकते हैं, न ही आप एक ऑपरेशन में सॉकेट से फाइल को पढ़ने की उम्मीद कर सकते हैं। सॉकेट बीएसडी सॉकेट से लेकर WinSock से लेकर .NET नेटवर्क कक्षाओं तक किसी भी नेटवर्क प्रोग्रामिंग एपीआई के लिए एपीआई को पढ़ता और लिखता है, सभी वांछित बाइट गिनती तक डेटा संचारित या प्राप्त करने जा रहे हैं।

यदि आप उदाहरण के लिए PHP सॉकेट_राइट के लिए प्रलेखन देखते हैं:

सॉकेट में सफलतापूर्वक लिखे गए बाइट्स की संख्या या विफलता पर FALSE लौटाता है। त्रुटि कोड को socket_last_error() के साथ पुनर्प्राप्त किया जा सकता है। त्रुटि का पाठ्य विवरण प्राप्त करने के लिए यह कोड सॉकेट_स्ट्रेरर () को पास किया जा सकता है।

नोट: यह सॉकेट_राइट () के लिए शून्य वापस करने के लिए पूरी तरह से मान्य है, जिसका अर्थ है कि कोई बाइट नहीं लिखा गया है। किसी त्रुटि की स्थिति में FALSE की जांच के लिए == ऑपरेटर का उपयोग करना सुनिश्चित करें।

आप आमतौर पर 4096 या 16384 जैसे ब्लॉक आकार का चयन करना चाहेंगे और लूप ट्रांसमिटिंग या उस ब्लॉक आकार को प्राप्त करना चाहेंगे जब तक कि आपको वांछित संख्या में बाइट्स प्रेषित या प्राप्त न हो जाएं। आपके कोड को आपके द्वारा कॉल किए जा रहे सेंड या रिसीव फंक्शन के रिटर्न वैल्यू की जांच करनी होगी और तदनुसार अपने फाइल पॉइंटर को एडजस्ट करना होगा। यदि प्रेषण 0 लौटाता है, तो इसका मतलब यह हो सकता है कि भेजें बफर भरा हुआ है (घातक नहीं) इसलिए भेजना जारी रखें (शायद नींद (0) देरी हो सकती है)। यदि रिटर्न 0 प्राप्त होता है, तो इसका आमतौर पर मतलब है कि दूसरे पक्ष ने कनेक्शन को स्पष्ट रूप से बंद कर दिया है।

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

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

10
Jeremiah Gowdy 25 जुलाई 2011, 00:42

आपको लगता है कि कैशिंग का समस्या से कोई लेना-देना नहीं है, इसका तात्पर्य यह है कि या तो आपके द्वारा प्रकाशित कोड के बाहर बहुत अधिक कार्यक्षमता है जो परिणाम को प्रभावित कर रही है या यह कि आप समस्या को समझने से बहुत दूर हैं।

बीएमपी फाइलों की संरचना को जाने बिना, मेरी पहली चिंता यह होगी कि आप फाइल को अतिरिक्त जानकारी से कैसे अलग करते हैं। कुछ चीजें जिन्हें आप आजमा सकते हैं...

  1. अगर '$कॉर्डिनेट्स' (एसआईसी) एक निश्चित आकार है, तो इसे संदेश के सामने रखें, पीछे नहीं
  2. PHP से भेजे गए आकार और प्राप्त आकार को लॉग करें।
  3. बेस 64 इसे भेजने से पहले बाइनरी फ़ाइल को एन्कोड करता है (और प्राप्त करने वाले अंत में डीकोड करता है)
2
symcbean 18 जुलाई 2011, 13:29

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

मैंने ASP.NET का उपयोग करके क्लाइंट की कोशिश की लेकिन वही परिणाम। मुझे लगता है कि यह क्लाइंट के साथ कोई समस्या नहीं है PHP यह निश्चित रूप से सॉकेट सर्वर की समस्या है

0
Sudantha 26 जुलाई 2011, 12:57