QT TCP Socket Communication (i)

Source: Internet
Author: User
Tags constructor file size port number

TCP is Transmission Control Protocol, the transmission protocol. Unlike UDP, it is a reliable transport protocol for connectivity and data flow. That is, it can make the data on one computer error-free to other computers on the network, so when we want to transfer a lot of data, we choose the TCP protocol.

The TCP protocol program uses the client/server model, provides the Qtcpsocket class in Qt to write client programs, and uses the Qtcpserver class to write server-side programs. We are on the server side of the port monitoring, once the client connection request, will emit a newconnection () signal, we can correlate this signal to our own slot function, data transmission. At the client, once the data arrives, a readyread () signal is emitted, and we can correlate this signal to receive the data. In fact, the most difficult thing to understand in the program is the program's sending and receiving, in order to let everyone better understand, we are only in this section to tell a simple transmission of the string example, in the next section to expand, to achieve arbitrary file transfer.

First, the server side.

In the server-side program, we listen to a port on the local host, which uses 6666, and then we correlate the newconnection () signal with the SendMessage () slot function that we wrote. This means that once a client connection request is performed, the SendMessage () function is executed, in which we send a simple string.

1. We new QT4 Gui application, project named "TCPServer", select Qtnetwork module, Base class select Qwidget. (Note: If some QT creator versions do not add a module, we will need to add a line of code in the project file Tcpserver.pro: qt + = network)

2. We add a label to the Widget.ui design area and change its objectname to Statuslabel, which is used to display some status information. As follows:

3. Make the following changes in the Widget.h file.

Add header file: #include <QtNetWork>

Add Private object: Qtcpserver *tcpserver;

To add a private slot function:

Private Slots:

void SendMessage ();

4. Make the changes in the Widget.cpp file.

Add code to its constructor:

TCPServer = new Qtcpserver (this);

if (!tcpserver->listen (qhostaddress::localhost,6666))

{//Listen to port 6666 on localhost, output error message if error, and close

Qdebug () << tcpserver->errorstring ();

Close ();

}

Connect (tcpserver,signal (Newconnection ()), This,slot (SendMessage ()));

Connection signals and corresponding slot functions

We use TCPServer's listen () function in the constructor to listen and then associate Newconnection () with our own SendMessage () function.

Below we implement the SendMessage () function.

void Widget::sendmessage ()

{

Qbytearray Block; For staging the data we want to send

Qdatastream out (&block,qiodevice::writeonly);

Writing data using a data stream

Out.setversion (Qdatastream::qt_4_6);

Set the version of the data flow to the same version used by the client and server side

out<< (quint16) 0;

Out<<tr ("Hello TCP!!!");

Out.device ()->seek (0);

out<< (quint16) (Block.size () –sizeof (quint16));

Qtcpsocket *clientconnection = Tcpserver->nextpendingconnection ();

We get the child sockets for the connection that has been established

Connect (clientconnection,signal (disconnected ()), Clientconnection,

SLOT (Deletelater ()));

Clientconnection->write (block);

Clientconnection->disconnectfromhost ();

Ui->statuslabel->settext ("Send message successful!!!");

After sending the data successfully, display the prompt

}

This is the data send function, we mainly introduce two points:

(1) In order to ensure that the client can receive the complete file, we are at the beginning of the data stream to write the full file size information, so that the client can be based on the size of the information to determine whether to accept the full file. And on the server side, we send the data in the first send the actual file size information, but the size of the file is unpredictable at first, so we first used out<< (quint16) 0; At the beginning of the block added a quint16 size space, That is, two bytes of space, which is used to place file size information behind. Then Out<<tr ("Hello TCP!!!"); Enter the actual file, here is the string. When the file input is completed we are using Out.device ()->seek (0); return to the beginning of block, add the actual file size information, that is, the following code, which is the size of the actual file:out<< (quint16) ( Block.size () –sizeof (quint16));

(2) On the server side we can use TCPServer's nextpendingconnection () function to obtain a TCP socket for a connection that has already been established, using it to complete the sending and other operations of the data. For example here, we associate the disconnected () signal with the Deletelater () slot function, and then we send the data

Clientconnection->write (block);

Then there is Clientconnection->disconnectfromhost (), which means that when the send is complete, the connection is disconnected, the disconnected () signal is emitted, and the last Call to Deletelater () The function guarantees that the socket clientconnection is deleted after the connection is closed.

5. So the server program is complete, let's run the program first.

Second, the client.

We send a connection request to the server in the client program and receive the data sent by the server when the connection succeeds.

1. We new QT4 Gui application, project named "TcpClient", select Qtnetwork module, Base class select Qwidget.

2, we add several label labels and two line edit and a button push button in Widget.ui.

Where "host" after the line edit objectname for Hostlineedit, "port number" after the Portlineedit.

The "info received" label objectname is Messagelabel.

3. Make the changes in the Widget.h file.

Add header file: #include <QtNetwork>

To add a private variable:

Qtcpsocket *tcpsocket;

QString message; Storing strings received from the server

Quint16 blockSize; Size information for the storage file

To add a private slot function:

Private Slots:

void Newconnect (); Connecting to a server

void Readmessage (); Receive data

void DisplayError (Qabstractsocket::socketerror); Display Error

4. Make the changes in the Widget.cpp file.

(1) Add code to the constructor:

Tcpsocket = new Qtcpsocket (this);

Connect (tcpsocket,signal (Readyread ()), This,slot (Readmessage ()));

Connect (tcpsocket,signal error (QABSTRACTSOCKET::SOCKETERROR)),

This,slot (DisplayError (Qabstractsocket::socketerror)));

Here are two signals associated with tcpsocket, and when there is data coming out of the readyread () signal, we execute the readmessage () function that reads the data. We execute the DisplayError () slot function when an error () signal is emitted.

(2) Implement the Newconnect () function.

void Widget::newconnect ()

{

blockSize = 0; Initialize it to 0

Tcpsocket->abort (); Cancel an existing connection

Tcpsocket->connecttohost (Ui->hostlineedit->text (),

Ui->portlineedit->text (). ToInt ());

Connect to the host, where you get the host address and port number from the interface

}

This function implements the connection to the server, which is called in the Click event Slot function of the Connect button.

(3) Implement the Readmessage () function.

void Widget::readmessage ()

{

Qdatastream in (Tcpsocket);

In.setversion (Qdatastream::qt_4_6);

Set the data flow version, which is the same as the server side

if (blocksize==0)//If you are just starting to receive data

{

Determines whether the received data has two bytes, that is, the size of the file information

If any are saved to the blocksize variable, no return, continue to receive data

if (Tcpsocket->bytesavailable () < (int) sizeof (quint16)) return;

In >> blockSize;

}

if (tcpsocket->bytesavailable () < blockSize) return;

Returns if not all data is received, continues to receive data

in >> message;

Storing the received data in a variable

Ui->messagelabel->settext (message);

Display the received data

}

This function implements the reception of the data, which corresponds to the sending function on the server side. First we want to get the file size information, and then according to the size of the file to determine whether to receive the full file.

(4) Implement the DisplayError () function.

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.