2011-02-04 16 views
7

तो, मेरे पास एमआईआरसी पोर्ट 1235 पर एक श्रवण (मेरे साथ भालू) बना रहा है और मैंने अपने स्थानीयहोस्ट सर्वर पर ऐसे पोर्ट से कनेक्ट करने के लिए एक PHP स्क्रिप्ट बनाने की कोशिश की है।PHP सॉकेट आधे काम कर रहे हैं

मेरा लोकहोस्ट एक स्वच्छ अपाचे + PHP है जिसमें एमआईआरसी दूसरे कंप्यूटर (लैन के अंदर) चल रहा है।

स्क्रिप्ट काम करता है आधा अधिकार के रूप में: 1) यह 1235 बंदरगाह 2) भेजता है को जोड़ता है $ i 2.1), लेकिन दूसरी तरफ कोई संदेश प्राप्त है पर (उर्फ मैं एक जुर्राब पढ़ घटना मिलता है लेकिन कोई पाठ पॉप अप होता है) 3) इसे पढ़ता सभी इनकमिंग संदेशों correclty 4) यह बंद कर देता है जब 'अंत' संदेश drumroll 5) यह तभी काम करता है, जबकि समारोह में मौजूद नहीं है। 5.1) उर्फ ​​इनिफी-लोडिंग। यह केवल गूंज जब सॉकेट 'अंत'

यहाँ कोड है, जो एक साधारण उदाहरण मैं php.net पर पाया है, अग्रिम धन्यवाद :) के माध्यम से बंद कर दिया है पता चलता

<?php 
//The Client 
error_reporting(E_ALL); 

$address = "192.168.1.101"; 
$port = 1235; 

/* Create a TCP/IP socket. */ 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 
if ($socket === false) { 
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; 
} else { 
    echo "socket successfully created.\n"; 
} 

echo "Attempting to connect to '$address' on port '$port'..."; 
$result = socket_connect($socket, $address, $port); 
if ($result === false) { 
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n"; 
} else { 
    echo "successfully connected to $address.\n<br>"; 
} 
$allow = true; 
$i = 0; 
while ($allow == true) 
{ 
    $i++; 
    echo "Sending $i to server.\n<br>"; 
    socket_write($socket, $i, strlen($i)); 

    $input = socket_read($socket, 2048); 
    if ($input == 'end') { 
     $allow = false; 
    } 
    echo "Response from server is: $input\n"; 
    sleep(5); 
} 

echo "Closing socket..."; 
socket_close($socket); 
?> 

इस मैं क्या मिलता है ब्राउज़र में, 'अंत' कहने

सॉकेट के बाद सफलतापूर्वक बनाया गया। पोर्ट '1235' पर '192.168.1.101' से कनेक्ट करने का प्रयास ... 192.168.1.101 से सफलतापूर्वक कनेक्ट किया गया। सर्वर को 1 भेज रहा है। सर्वर से प्रतिक्रिया है: सर्वर से ठीक प्रतिक्रिया है: अंत

इस mIRC में है:

परीक्षण: 89.152.172.21 में है! Blockquote

पढ़ पास अगर मैं 60 के लिए यह एक घंटे के लिए काम छोड़ दिया था, गुणा "पढ़ें" और "भेजने एन सर्वर से 1" लेकिन यह केवल जुर्राब बंद करने के बाद पता चलता है (या stoping द्वारा जबकि)

+1

आप पोस्ट कर सकते हैं क्या 'echos' इसे बाहर थूकना है जब आप उस चलाने? इसे डीबग करने में सहायक हो सकता है। – xil3

+0

कोई फर्क नहीं करना चाहिए 'echos' बाहर थूक दिया है करने के लिए :) – MoshMage

उत्तर

2

आप "सादे" socket_write() और socket_read() कॉल नहीं है।दुर्भाग्य से सॉकेट कार्यों डिजाइन द्वारा अविश्वसनीय (BSD सॉकेट से विरासत में मिली है कि व्यवहार) कर रहे हैं। तुम बस socket_write() कॉल कर सकते हैं नहीं है और यह वास्तव में बाइट्स लिखने के लिए उम्मीद (के रूप में अजीब के रूप में यह लग रहा है ...)

पीएचपी मैनुअल बोली:

socket_write() जरूरी दिया बफर से सभी बाइट्स बारे में नहीं है। यह मान्य है कि, नेटवर्क बफर इत्यादि के आधार पर, केवल एक निश्चित मात्रा में डेटा, यहां तक ​​कि एक बाइट भी लिखा जाता है, हालांकि आपका बफर अधिक होता है। आपको देखना होगा ताकि आप अनजाने में अपने शेष डेटा को प्रेषित करना न भूलें।

आपको यह जांचना होगा कि कितने बाइट लिखे गए हैं और जब तक आप चाहते थे, तब तक पुनः प्रयास करना जारी रखें।

ही पढ़ने के लिए चला जाता है। कॉल पढ़ें के रूप में ज्यादा के रूप में आप या उससे कम अनुरोध किया है और आप कॉल फिर से प्रयास करने की उम्मीद कर रहे हैं पढ़ सकते हैं।

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


आप एपीआई कि इस तरह के PITA नहीं है चाहते हैं, तो streams का उपयोग करने के बजाय, जो विश्वसनीय पढ़ता है/लिखता है।

यदि आपको आवश्यक रूप से PHP की आवश्यकता नहीं है, तो Node JS पर एक नज़र डालें, जो लंबे समय तक नेटवर्क कनेक्शन वाले कार्यक्रमों के लिए विशेष रूप से डिज़ाइन किया गया सर्वर/वातावरण है।

+0

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

0

बदलें

socket_write($socket, $i, strlen($i)); 

करने के लिए:

socket_write($socket, strval($i), strlen(strval($i))); 

आप एक पूर्णांक प्रदान कर रहे हैं जहां PHP एक स्ट्रिंग की अपेक्षा करता है।

+3

इस पोस्ट अद्यतन? – zanlok

+0

भले ही यह किया गया हो, फिर भी मुझे एक वास्तविक न्यूलाइन के लिए एमआईआरसी – MoshMage

0
दस्तावेज में नोटों में से एक से

: http://php.net/manual/en/function.socket-write.php

कुछ क्लाइंट (उदाहरण के लिए फ्लैश के XMLSocket) पढ़ने घटना सक्रिय नहीं होगा जब तक एक नई लाइन प्राप्त कर रहा है।

तो अपने कोड बदलने का प्रयास करें:

socket_write($socket, $i, strlen($i)); रहे हैं: socket_write($socket, $i.'\n', strlen($i)+1);

+0

डबल कोट्स पर 0 आरसीवीडी बाइट्स मिलते हैं। – igorw

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