2010-10-24 98 views
2

我试图用一个基本的Qt tcp客户端连接一个非常基本的扭曲的“你好世界”服务器。Qt C++ tcp客户端与python扭曲的服务器

客户端使用这些信号:

connect(&socket, SIGNAL(connected()), this, SLOT(startTransfer())); 
connect(&socket, SIGNAL(readyRead()), this, SLOT(readServer())); 

,然后readServer()看起来是这样的:

ui->resultLabel->setText("Reading.."); 
QDataStream in(&socket); 
//in.setVersion(QT_4_0); 

if (blockSize == 0) { 
    if (socket.bytesAvailable() < (int)sizeof(quint16)) 
     return; 

    in >> blockSize; 
} 

if (socket.bytesAvailable() < blockSize) 
    return; 

QString theResult; 
in >> theResult; 
qDebug() << in; 
qDebug() << theResult; 
ui->resultLabel->setText(theResult); 

我使用的是用于测试目的的服务器是一个简单的例子抓住断扭曲的的docs

from twisted.internet.protocol import Protocol, Factory 
from twisted.internet import reactor 

### Protocol Implementation 

# This is just about the simplest possible protocol 
class Echo(Protocol): 
    def dataReceived(self, data): 
     """ 
     As soon as any data is received, write it back. 
     """ 
     self.transport.write(data) 


def main(): 
    f = Factory() 
    f.protocol = Echo 
    reactor.listenTCP(8000, f) 
    reactor.run() 

if __name__ == '__main__': 
    main() 

readServer()被称为很好,但它似乎从来没有收集t任何数据。我曾经在某处读过,这可能与QDataStream的< <运算符有关,因为python并不像Qt所期望的那样完全发送它。

我承认我对C++或Qt不是很了解,但是项目的想法是编写一个客户端与现有的扭曲服务器一起工作,所以虽然客户端可以改变,但我没有选择但要使它与这台服务器一起工作。

在此先感谢您的帮助。

回答

2

问题原来是QDataStream,它显然不仅仅是对它正在阅读的数据有点特别的了解。

谢天谢地,我发现了QDataStream :: readRawData,它喜欢python发送的数据好得多(进一步我发现这与twisted没有任何关系,但是python套接字实现本身。)最终代码如下所示:

//use socket to construct a QDataStream object, like before 
QDataStream in(&socket); 
//in.setVersion(QDataStream::Qt_4_0); 
char buffer[1024] = {0}; 
//readRawData takes a char to dump to and the length, 
//so I'm sure there is a better way to do this. It worked for my example. 
in.readRawData(buffer, socket.bytesAvailable()); 
QString result; 
result = buffer; 
ui->resultLabel->setText(result); 
1

了解TCP的一个重要事情是,它不是传输特定大小的消息(或“块”)。它是一个字节流的传输。当你写类似:

if (socket.bytesAvailable() < (int)sizeof(quint16)) 
    return; 

那么你最好有一个循环的地方,我们再次调用此代码,因为没有保证你周围的第一次会得到你需要让过去这个所有字节检查。

你没有分享任何负责发送数据到echo服务器的代码,所以不可能真正知道你的Qt客户端为什么没有得到你期望得到的数据,但考虑到上面的I如果涉及对不完整数据的不正确缓冲,则不会感到惊讶。

请确保如果因为没有足够的数据而决定不从套接字中读取数据,请稍后再尝试读取更多数据。一个好的方法是实际上总是将数据读入应用程序缓冲区,这样您就可以使用select()或epoll(),或者在套接字上有更多可用数据时告诉您什么。然后在应用程序缓冲区上运行。

+0

谢谢,我已阅读了很多关于此的内容,可能需要阅读更多内容。正如我所说,这是我对此的第一次破解,尽管这并不是问题,但我会牢记它。 – jsullivan88 2010-10-24 23:11:11