The understanding of QT Network programming qtcpserver and Qtcpsocket

Source: Internet
Author: User
Tags chop socket

Some time ago through the debugging Qt source code, the general understanding of the QT event mechanism, signal slot mechanism. After all, ability and time are limited. Some places do not understand very clearly.

Development environment: Linux ((Fedora), QT version (qt-everywhere-opensource-src-4.7.3).

QT Network programming is more commonly used in two classes: Qtcpserver and Qtcpsocket. Of course, there are UDP classes (not described here).

The operation of these two classes is relatively straightforward.


Basic operation of Qtcpserver:

1, call listen listening port.

2. Connect the signal newconnection, call nextpendingconnection in the slot function to get the socket connected.


Basic operation of Qtcpsocket:

1. Call Connecttohost to connect to the server.

2. Call waitforconnected to determine if the connection is successful.

3, connect the signal Readyread slot function, read data asynchronously.

4, call Waitforreadyread, block read data.


The event loop is entered after calling App.exec () in the main function. Callback in the event loop of Qt with Qeventloop::p rocessevents. In this function, Qabstracteventdispatcher is called::p rocessevents.

QT offers different eventdispatcher for different platforms. I'm using Linux. Next you call Qeventdispatcherunix::p rocessevents. Doselect,select.

The order of function calls can be verified by debugging the source code. In fact, QT network programming, the bottom is through select implementation. may be related to cross-platform, using SELECT. Linux has a better API (Poll,epoll) than select.

Through debugging, it can be found that both newconnection and Readyread are related to select.

Because the call is select, the server side will certainly have a problem with the number of monitoring file descriptors. The select default is 1024. The QT default is also 1024. The server side is calling Nextpendingconnection. A Qtcpsocket object is created. This object is automatically deleted when the Qtcpserver object is deleted. You can also delete it manually, avoid wasting memory, and delete the object when the object is disconnected. When the object is disconnected, the select call clears the descriptor and does not affect the number of file descriptors. If memory is sufficient, you do not need to care about the object.


Next, we introduce the readyread signal. This signal is used more.

This signal is triggered when the data is to be read. However, before triggering the signal, QT attempts to read the Bytestoread data, which exists in the internal buffer.

Here is the QT source snippet

    Qint64 bytestoread = socketengine->bytesavailable (); 
#ifdef q_os_linux if (Bytestoread > 0)//# # # See Setsocketdescriptor () Bytestoread + = addtobytesavailable;
        #endif if (Bytestoread = = 0) {//Under heavy load, certain conditions can trigger read notifications For sockets notifiers on which there is no activity. If we continue//to read 0 bytes from the socket, we'll trigger behavior similar//to that which Signa LS a remote close. When we hits this condition,//We try to read 4k of data from the socket, which would give us either//an
        Eagain/ewouldblock If the connection is alive (i.e., the remote//host has _not_ disappeared).
    Bytestoread = 4096; } if (Readbuffermaxsize && bytestoread > (readbuffermaxsize-readbuffer.size ())) Bytestoread = Rea

    Dbuffermaxsize-readbuffer.size ();
    Read from the socket, store data in the read buffer. Char *ptr = readbuFfer.reserve (Bytestoread);
    Qint64 readbytes = Socketengine->read (ptr, bytestoread);
        if (readbytes = =-2) {//No bytes currently available for reading.
        Readbuffer.chop (Bytestoread);
    return true;
 } readbuffer.chop (int (Bytestoread-(readbytes < 0? qint64 (0): readbytes)));
Qint64 qnativesocketengineprivate::nativebytesavailable () const
{
    int nbytes = 0;
    Gives shorter than true amounts on Unix domain sockets.
    Qint64 available = 0;
#ifdef Q_os_symbian
	if (:: Ioctl (Socketdescriptor, Fionread, (char *) &nbytes) >= 0)
#else
    if (qt_ Safe_ioctl (Socketdescriptor, Fionread, (char *) &nbytes) >= 0)
#endif
        available = (qint64) nbytes;

    return available;
}
Steps to read data:

1. Get the data length that the system can read through the IOCTL.

2, more 4K data in Linux system (related to Linux domain sockets).

3. If you call Setreadbuffersize () to set the buffer size. Recalculate Bytestoread. As can be seen from the code, only bytestoread big words, only recalculate. If the readbuffermaxsize is set too large, it will not be recalculated.

4. Call the read function to try to read the Bytestoread length data. Returns the actual read data length readbytes. Through the debugging can see Readbytes and bytestoread difference is not many.

The bytesavailable () function returns the buffer length. If Readbuffermaxsize is not set, the function return value depends primarily on the IOCTL system call. The system call is related to the state in which the system is currently running.

Problems that may occur:

1, when the readyread signal is triggered, but the length of the buffer is less than the data sent at the other end. This will trigger multiple readyready signals. If the length of the buffer is read inside a slot function, the data will be incomplete, and processing will definitely be problematic. A method is provided in the QT example. Add the length of the data to the head of the sending data. The data is read only when Bytesavailable is greater than the length of the data.


2, the system API call read is read from the system buffer inside the data. If the system buffer is full. The previous will be overwritten. But there is also a buffer in Qt. If one end sends data. The other end does not read data from the QT buffer. Then QT will be unrestricted to read the data from the system buffer to place its own internal buffer. Finally, the stack is full and the system exits unexpectedly.
To learn more about the QT network, you can build a debugging environment. Debug yourself to analyze the source code, find the reason.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.