2012-01-18 6 views
9

का उपयोग कर क्यूटी बिडरेक्शनल क्लाइंट सर्वर मैं एक बिडरेक्शनल क्लाइंट-सर्वर प्रोग्राम को लागू करने का प्रयास कर रहा हूं, जहां क्लाइंट और सर्वर एक दूसरे के बीच क्रमबद्ध ऑब्जेक्ट पास कर सकते हैं। मैं क्यूटी (QTcpSocket और QTcpServer) का उपयोग करके ऐसा करने की कोशिश कर रहा हूं। मैंने जावा में इस तरह के कार्यक्रमों को लागू किया है, लेकिन मैं यह नहीं समझ सकता कि क्यूटी का उपयोग करके इसे कैसे किया जाए। मैंने fortune client और fortune server उदाहरणों की जांच की है ... लेकिन जो मैं देख सकता हूं, क्लाइंट बस सर्वर को सिग्नल कर रहा है, और सर्वर इसे कुछ डेटा भेजता है। मुझे क्लाइंट और सर्वर की ऑब्जेक्ट्स को आगे और आगे भेजने की आवश्यकता है। मैं एक पूर्ण समाधान की तलाश नहीं कर रहा हूं, जो कुछ मैं ढूंढ रहा हूं वह सही दिशा में कुछ मार्गदर्शन है।QTcpSocket और QTcpServer

मैंने कुछ कोड लिखा, जो कनेक्शन स्वीकार करता है, लेकिन डेटा स्वीकार नहीं करता है।

सर्वर

इस वर्ग के सर्वर है, इसे एक कनेक्शन स्वीकार करना और बफर के आकार को आउटपुट करना चाहिए जो भेजा जा रहा है। हालांकि यह outputting है 0

#include "comms.h" 

Comms::Comms(QString hostIP, quint16 hostPort) 
{ 
    server = new QTcpServer(this); 
    hostAddress.setAddress(hostIP); 
    this->hostPort = hostPort; 


} 

void Comms::attemptConnection(){ 
    connect(server, SIGNAL(newConnection()), this, SLOT(connectionAccepted())); 
    //socket = server->nextPendingConnection(); 
    server->listen(hostAddress,hostPort); 
    //receivedData = socket->readAll(); 
} 

void Comms::connectionAccepted(){ 
    qDebug()<<"Connected"; 
    socket = new QTcpSocket(server->nextPendingConnection()); 

    char* rec = new char[socket->readBufferSize()]; 
    qDebug()<<socket->readBufferSize(); 
} 

ग्राहक

इस वर्ग के ग्राहक है। यह स्ट्रिंग 'हैलो' भेजना चाहिए। यह इसे सफलतापूर्वक भेजता है (मेरी जानकारी के लिए)

#include "toplevelcomms.h" 
#include "stdio.h" 

TopLevelComms::TopLevelComms(QString hostIP, quint16 hostPort) 
{ 
    tcpSocket = new QTcpSocket(); 
    hostAddress.setAddress(hostIP); 
    this->hostPort = hostPort; 
} 


void TopLevelComms::connect(){ 
    tcpSocket->connectToHost(hostAddress,hostPort,QIODevice::ReadWrite); 
    //tcpSocket->waitForConnected(1); 

    QString string = "Hello"; 
    QByteArray array; 
    array.append(string); 
    qDebug()<<tcpSocket->write(array); 
} 

कृपया मुझे बताओ कि मैं गलत क्या कर रहा है, या मुझे स्थापित करने मैं क्या क्यूटी में चाहते हैं के सामान्य तर्क बताओ।

उत्तर

9

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

void TopLevelComms::connect(){ 
    tcpSocket->connectToHost(hostAddress,hostPort,QIODevice::ReadWrite); 
    if(tcpSocket->waitForConnected()) // putting 1 as parameter isn't reasonable, using default 3000ms value 
    { 
     QString string = "Hello"; 
     QByteArray array; 
     array.append(string); 
     qDebug()<<tcpSocket->write(array); 
    } 
    else 
    { 
     qDebug() << "couldn't connect"; 
    } 
} 

नोट:: आप अपने "क्लाइंट" कोड बदलना चाहिए आप भी अगर तुम सुनने के लिए

void Comms::attemptConnection(){ 
    connect(server, SIGNAL(newConnection()), this, SLOT(connectionAccepted())); 
    //socket = server->nextPendingConnection(); 

    if(server->listen(hostAddress,hostPort)) 
    { 
     qDebug() << "Server listening"; 
    } 
    else 
    { 
     qDebug() << "Couldn't listen to port" << server->serverPort() << ":" << server->errorString(); 
    } 
    //receivedData = socket->readAll(); 
} 

और अंत में कर रहे हैं की जाँच नहीं की। ध्यान दें कि QTcpServer :: nextPendingConnection() लौट QTcpSocket, इसलिए बजाय लेने कि नया कनेक्शन आप माता पिता के रूप nextPendingConnection के साथ नए QTcpSocket बनाने

void Comms::connectionAccepted(){ 
    qDebug()<<"Connected"; 
    // WRONG! it will use QTcpSocket::QTcpSocket(QObject * parent) 
    //socket = new QTcpSocket(server->nextPendingConnection()); 
    // use simple asign 
    socket = server->nextPendingConnection(); 
    // move reading to slot 
    connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket())); 
} 
अब

हम अलग स्लॉट

void Comms::readSocket() 
{ 
    // note that dynamic size array is incompatible with some compilers 
    // we will use Qt data structure for that 
    //char* rec = new char[socket->readBufferSize()]; 
    qDebug()<<socket->readBufferSize(); 
    // note that QByteArray can be casted to char * and const char * 
    QByteArray data = socket->readAll(); 
} 

मैं चाहिए करने के लिए पढ़ने के लिए कदम होगा की मान लें, कि इस तरह के छोटे कोड नमूने के लिए यह बहुत सारी त्रुटियों है। आपको टीसीपी/आईपी कनेक्शन के बारे में कुछ जानकारी प्राप्त करने की आवश्यकता है। वे धाराएं हैं और कोई वारंटी नहीं है कि पूरे डेटा खंड आपको एक बार

+1

धन्यवाद बहुत धन्यवाद, मैं सॉकेट में डेटा भेजने में सक्षम था।हालांकि मुझे अभी भी किसी कारण से 0 का बफर आकार मिल रहा है। कोई विचार क्यों? – PTBG

+0

दस्तावेज़ों से "0 के एक पढ़ने वाले बफर आकार (डिफ़ॉल्ट) का अर्थ है कि बफर के पास कोई आकार सीमा नहीं है, यह सुनिश्चित करना कि कोई डेटा खो गया न हो"। इसलिए यह वास्तविक सामग्री पर कोई संकेत नहीं देता है। आपको 'सॉकेट-> आकार()' या 'सॉकेट-> बाइट्स उपलब्ध()' का उपयोग करना चाहिए –

4

ऐसा लगता है कि आपके पास समय समस्या है। चूंकि आपका क्लाइंट और सर्वर अलग-अलग प्रक्रियाएं हैं, इसलिए आपके सर्वर की connectionAccepted() फ़ंक्शन सॉकेट से पढ़ने की कोशिश करने से पहले TopLevelComms::connect() की संपूर्णता (नेटवर्क डेटा ट्रांसफर के साथ) निष्पादित की जा रही है, इस तरह से आप गारंटी नहीं दे सकते हैं।

मुझे लगता है कि अगर आप QTcpSocket के waitForReadyRead() समारोह का लाभ लेने, तो आप बेहतर किस्मत होना चाहिए:

void Comms::connectionAccepted(){ 
    qDebug()<<"Connected"; 
    socket = new QTcpSocket(server->nextPendingConnection()); 

    if(socket->waitForReadyRead()) { 
     char* rec = new char[socket->readBufferSize()]; 
     qDebug()<<socket->readBufferSize(); 
    } 
} 
संबंधित मुद्दे