2012-07-26 17 views
8

मुझे दिलचस्पी है कि कैसे QTcpServer धागे और अवरुद्ध करने के दृश्यों के पीछे काम करता है। QTcpServer में listen() विधि है जो तुरंत लौटती है। अगर सुनना सफलतापूर्वक शुरू हुआ है तो सर्वर newConnection() सिग्नल उत्सर्जित करेगा। मुझे लगता है कि listen() विधि वापस आ गई है जब सर्वर सुन रहा है (यह मुख्य धागे पर है)।QTcpServer वास्तव में कनेक्शन के लिए कैसे सुन रहा है

//main.cpp 
int main(int argc, char* argv[]) 
{ 
    QCoreApplication app; 
    MyServer server; 
    app.exec(); 
} 

//MyServer.cpp 
MyServer::MyServer(QObject *parent) : QObject(parent) 
{ 
    this->server = new QTcpServer(this); 
    connect(server, SIGNAL(newConnection()), this, SLOT(on_newConnection())); 
    if (!server->listen(QHostAddress::Any, 1234)) 
     //do something in case of error 
} 
void MyServer::on_newConnection() 
{ 
    QTcpSocket* socket = server->nextPendingConnection(); 
    //do some communication... 
} 

QTcpServer पर निर्भर है एक QCoreApplication (या शायद एक QRunLoop) मौजूदा और नेटवर्क की घटनाओं recive करने के लिए चल रहा है: एक QTcpServer के साथ एक सांत्वना आवेदन के सामान्य उदाहरण कुछ इस तरह है। क्या यह QCoreApplication::exec() के बिना ठीक से काम कर सकता है?

उत्तर

16

मैं QtCore और QtNetwork मॉड्यूल के स्रोत कोड के माध्यम से ड्रिलिंग कर रहा हूं।

Aperantly, QTcpServer दो मोड में काम कर सकते हैं: तुल्यकालिक और अतुल्यकालिक

तुल्यकालिक मोड में listen() फोन करने वाले waitForNewConnection() जो एक अवरुद्ध विधि है कॉल कर सकते हैं बुला के बाद (जब तक किसी को सुनने के पोर्ट से कनेक्ट धागा सो जाएगा)। इस तरह QTcpServer किसी ईवेंट लूप के बिना थ्रेड में काम कर सकता है।

असीमित मोड QTcpServernewConnection() सिग्नल उत्सर्जित करेगा जब एक नया कनेक्शन स्वीकार किया गया था। लेकिन ऐसा करने में सक्षम होने के लिए एक घटना लूप चलाना चाहिए। QCoreApplication अंतर्निहित QEventLoop और QAbstractEventDispatcher (एक सार वर्ग, ठोस प्रकार ओएस पर निर्भर है, उदाहरण के लिए QEventDispatcherUNIX)। यह इवेंट प्रेषक सॉकेट पर स्थितियों के लिए निगरानी कर सकता है (फाइल डिस्क्रिप्टर द्वारा प्रतिनिधित्व)। इसमें एक विधि registerSocketNotifier(QSocketNotifier*) है। इस विधि को QSocketNotifier वर्ग के निर्माता द्वारा बुलाया जाता है, जो QTcpServer हर बार listen() कहलाता है। एकमात्र सिस्टम कॉल जिसे QTcpServer::listen() कहा जाता है, कहा जाता है, बेशक, listen() जो तुरंत लौटाता है, ईवेंट लॉप चालू होने पर सभी असली जादू होता है। इवेंट लूप (प्रेषक का उपयोग करके) मॉनीटर करेगा कि पंजीकृत सॉकेट पर एक निश्चित शर्त है या नहीं। यह select() सिस्टम कॉल को कॉल करता है जो कुछ शर्तों के लिए एक या अधिक फ़ाइल डिस्क्रिप्टरों को निगरानी (कर्नेल द्वारा) प्राप्त करता है (यदि डेटा पढ़ा जा सकता है, यदि डेटा लिखा जा सकता है, या यदि कोई त्रुटि हुई है)। जब तक सॉकेट की शर्तों को पूरा नहीं किया जाता है, तब तक कॉल थ्रेड को अवरुद्ध कर सकता है, या कुछ समय बीतने के बाद यह वापस आ सकता है और सॉकेट पर शर्तों को पूरा नहीं किया गया था। मुझे यकीन नहीं है कि अगर क्यूटी select() पर कॉल किए गए समय के साथ या बिना (अनिश्चित काल तक अवरुद्ध करने के लिए) कॉल कर रहा है, तो मुझे लगता है कि यह कुछ जटिल तरीके और परिवर्तनीय में निर्धारित है। तो आखिर में जब सॉकेट पर शर्त पूरी हो गई, तो घटना प्रेषक उस सॉकेट के लिए QSocketNotifier को सूचित करेगा, जो टर्न में QTcpServer को सूचित करेगा जो सॉकेट को सुन रहा है, जो कनेक्शन स्वीकार करेगा, और newConnection() सिग्नल को उत्सर्जित करेगा।


तो QTcpServer घटना पाश/सॉकेट निगरानी प्रणाली में फोन ही नहीं है, लेकिन यह QSocketNotifier जो यह कनेक्शन की अतुल्यकालिक प्राप्त करने के लिए उपयोग करता है के माध्यम से यह पर निर्भर है।

जब तुल्यकालिक विधि waitForNewConnection() कहा जाता है तो यह केवल QSocketNotifier सामान को छोड़ देता है और accept() पर कॉल करता है जो आने वाले कनेक्शन तक धागे को अवरुद्ध करता है।

+0

बहुत अच्छा। अब मैं समझता हूं कि क्यूटी (मैं पीईक्यूटी का उपयोग करता हूं) में एप्लिकेशन इवेंट लूप को निष्पादित करने से पहले क्यों कॉलिंग सुनता हूं, जिसके परिणामस्वरूप 'नया कनेक्शन' सिग्नल नहीं मिलता है। खुदाई के लिए धन्यवाद। – Trilarion

0

क्यूटी की कार्यक्षमता QCoreApplication के मुख्य समारोह पाश अंदर होता है "पर्दे के पीछे" के अधिकांश: संकेत/स्लॉट, टाइमर, आदि
एक उदाहरण जावास्क्रिप्ट होगा - आप एक घटना के लिए बाध्य है, लेकिन घटना पाश ब्राउज़र द्वारा संसाधित किया जाता है।

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