QTcpSocker, QTcpServer

来源:互联网 发布:阿里云服务器推荐 编辑:程序博客网 时间:2024/05/18 01:18

1、  QTcpSocket, QTcpServer, C++ GUI Programming

        Chapter15-Tripplanner示例中是如何接收socket数据的?

        关键接口:

        void QIODevice::readyRead () [signal]

        This signal is emitted once every time new data is available for reading from the device.

        可知,只要有新的数据传来,都会触发该signal。

        qint64 QAbstractSocket::bytesAvailable () const [virtual]

        Returns the number of incoming bytes that are waiting to be read.

 

        发送socket数据时是按照如下指定的格式来发送的,如server发送:The Trip Server’s blocks,数据的格式如下:

quint16

Block size in bytes (excluding this field)

QDate

Departure date

QTime

Departure time

quint16

Duration (in minutes)

quint8

Number of changes

QString

Train type

        第一个数据表示该datablock的大小,它的类型是quint16;第二个表示Departure date,它的类型是QDate;依次类推。注意,server在发送完有效数据后,会再发送一个0XFFFF,表示该data block结束。(注,表格中红色部分是有效数据)

        out << quint16(0xFFFF);

        在接收socket数据时,也是按照同样的顺序来接收的。在bytesAvailable后,会触发readyRead,接收函数调用:in >> nextBlockSize;来接收第一个数据,也就是quint16类型的表示有效data block大小的数据。然后用以下接口来做判断:

if(nextBlockSize == 0xFFFF) {      closeConnection();      statusLabel->setText(tr("Found %1 trip(s)").arg(row));      break;} if(tcpSocket.bytesAvailable() < nextBlockSize)     break;

         它的含义是,如果接收到的数据是0XFFFF,表示此次接收结束;如果tcpSocket.bytesAvailable()< nextBlockSize说明这个data block的有效数据(指从Departure date到Train type的数据)还没有都read available,则退出函数;直到有新的数据到达,且可bytesAvailable的大小等于有效数据的大小,才能接着往下执行。

2、对TCP和UDP来说,服务器端和客户端的区别是什么?

         Chapter15-Tripplanner示例使用TCP的流程如下:


         注意,server也是通过建立QTcpSocket对象来和clientQTcpSocket进行通信的。

        问题:server在没有client请求的情况下,可以主动向client发送数据吗?

        可以,只要建立并保持client和server之间的socket连接,就可以。

3、TCP

    TCP is a stream-oriented protocol. For applications, the data appears to be a long stream, rather like a large flat file. The high-level protocols built on top of TCP are typically either line-oriented or block-oriented:

Line-oriented protocols transfer data as lines of text, each terminated by a newline.

Block-oriented protocols transfer data as binary data blocks. Each block consists of a size field followed by that much data.

4、实现QTcpServer向client发送数据的两种方法

1)Chapter15-Tripplanner使用的方法

         调用这个接口实现:

         void QTcpServer::incomingConnection ( int socketDescriptor) [virtual protected]

         This virtual function is called by QTcpServer when a new connection is available. The socket Descriptor argument is the native socket descriptor for the accepted connection.

         知:在QTcpServer与一个client建立connect后,会自动调用incomingConnection,并传进一个socketDescriptor,可以用如下代码建立一个QTcpSocket来和client进行通信:

voidTripServer::incomingConnection(int socketId){    tcpsocket->setSocketDescriptor(socketId);}

       其中,tcpsocket = new QTcpSocket。这样就建立起server端QTcpSocket与client端QTcpSocket的连接。

2)QT-NetWork-Example里各server例程使用的方法

         调用如下两个接口实现:

       void QTcpServer::newConnection () [signal]

       Thissignal is emitted every time a new connection is available.

       QTcpSocket * QTcpServer::nextPendingConnection ()[virtual]

       Returnsthe next pending connection as a connected QTcpSocket object.

         用如下代码实现:

connect(tcpServer,SIGNAL(newConnection()), this, SLOT(sendFortune()));voidServer::sendFortune() {...     QTcpSocket *clientConnection =tcpServer->nextPendingConnection();... }

5、讲解多线程TCP服务器的例程

        http://www.bogotobogo.com/Qt/Qt5_QTcpServer_Multithreaded_Client_Server.php,用run函数实现多线程。

        http://www.qt-coding.com/category/applications/,用moveToThread实现多线程。

0 0
原创粉丝点击