Directory
1. review
1.1 UDP and TCP
1.2 IP address and port number
2. Preparation
3. Programming content
1. Review
1.1 UDP and TCP
The same point of UDP and TCP protocols: both exist in the transport layer
- TCP (Transmission Control Protocol):
It is a connection-oriented transport layer protocol, which can provide high-reliability communication (that is, data is correct, data is not lost,
Data without out-of-sequence, data without duplicate arrival communication)
Applicable situation:
1. It is suitable for communication that requires high transmission quality and transmits a large amount of data.
2. When reliable data transmission is required, the TCP protocol is usually used
3. Functions related to user login account management of MSN/QQ and other instant messaging software usually use TCP protocol
- UDP : User Datagram Protocol
UDP (User Datagram Protocol) is an unreliable connectionless protocol. Since no connection is required before data is sent, efficient data transmission is possible.
Applicable situation:
1. Send small size data (such as when querying the IP address of the DNS server)
2. UDP is used in networks where it is difficult to receive data and give a response.
3. Suitable for broadcast/multicast communication.
4. The point-to-point text communication and audio and video communication of instant messaging software such as MSN/QQ/Skype usually use UDP protocol
5. Streaming media, VOD, VoIP, IPTV and other network multimedia services usually use UDP for real-time data transmission
1.2 IP address and port number
- IP address
basic concept:
The IP address is the identification of the host in the Internet, and the host in the Internet must have an IP address to communicate with other machines.
- Port number
basic concept:
In order to distinguish which process a data packet received by a host should be forwarded to for processing, the port number is used to distinguish.
Well-known ports: 1~1023 (1~255 are well-known ports, 256~1023 ports are usually occupied by UNIX systems)
Registered ports: 1024~49151
Dynamic or private port: 49152~65535
Suggestion for the port number of the custom program: 2000-65535, remove the serial number, such as 8888
2. Preparation
Like the database, the network function also needs to add the network module in the .pro file.
Qt’s TCP communication structure diagram is shown below (the principle is roughly shown in the figure below, but the specific API is different).
3. Programming Content
To implement a TCP-based chat program this time, the classes that need to be used are:
- QTcpServer
Server management class: manages multiple connections to the server, directly inheriting QObject, so it does not have IO capabilities.
The relevant functions are as follows:
// Constructor QTcpServer::QTcpServer(QObject * parent = 0)
// The server starts monitoring and waits for the client to initiate a connection // Parameter 1: Which IP address to monitor the request from, the default value is not limited to the IP address, and the QHostAddress class is the encapsulation class of the IP address. // Parameter 2: server port number // Return value: monitor the opening result bool QTcpServer::listen( const QHostAddress & address = QHostAddress::Any, quint16 port = 0)
// Notification signal for new connection establishment void QTcpServer::newConnection() [signal]
// Is the server still listening bool QTcpServer::isListening() const
// close the server void QTcpServer::close()
// Return a ready connection object, which is used to perform IO operations with a client QTcpSocket * QTcpServer::nextPendingConnection() [virtual]
- QTcpSocket
TCP connection class: perform network IO operations, and indirectly inherit the QIODevice class.
The relevant functions are as follows:
// Constructor QTcpSocket::QTcpSocket(QObject * parent = 0)
// connect to the server // Parameter 1: IP address of the server // Parameter 2: The port number of the server // Parameter 3: Read and write mode, the default is readable and writable void QAbstractSocket::connectToHost(const QString & amp; hostName, quint16 port, OpenMode openMode = ReadWrite) [virtual]
// Whether the connection is open bool QIODevice::isOpen() const
// close the connection void QIODevice::close() [virtual]
// Get the opposite IP address encapsulation class object, if there is no connection, return QHostAddress::Null QHostAddress QAbstractSocket::peerAddress() const
// The signal emitted by disconnection void QAbstractSocket::disconnected() [signal]
// The signal emitted when there is data to read void QIODevice::readyRead() [signal]
- QTextStream
Text stream class: It is an auxiliary class for efficient text data IO.
// Constructor // The parameter is the derived class object of QIODevice QTextStream::QTextStream(QIODevice * device)
// send string // The parameter must be of type QString, be careful not to use const char* // The return value is a reference of the current type, indicating that chain calls are supported, so the sent content is appended continuously QTextStream & amp; QTextStream::operator<<(const QString & amp; string)
// Read the content with a maximum value of maxlen characters to the return value QString QTextStream::read(qint64 maxlen)
// Read a line of characters with the maximum number of characters maxlen to the return value QString QTextStream::readLine(qint64 maxlen = 0)
// read all characters to the return value // QString QTextStream::readAll()
Client: (QTcpSocket)
① Create a QTcpSocket object
②When the object is successfully connected to the server, a connected signal will be sent
③Call the member function connectToHost to connect to the server, the required parameters are address and port number
④The slot function of the connected signal starts sending data
⑤Use write to send data, read to receive data
dialog.h
#ifndef DIALOG_H #define DIALOG_H #include <QtWidgets> //connection class #include <QTcpSocket> //file stream class #include <QTextStream> #include <QTcpServer> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); private: Ui::Dialog *ui; QTcpSocket *client; //Connection object private slots: void btnConnClickedSlot(); void btnSendClickedSlot(); //Connection and disconnection detection slot function void connectedSlot(); void diaconnectedSlot(); void readReadSlot(); }; #endif // DIALOG_H
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); connect(ui->pushButtonConn,SIGNAL(clicked()),this,SLOT(btnConnClickedSlot())); connect(ui->pushButtonSend,SIGNAL(clicked()),this,SLOT(btnSendClickedSlot())); //set window as top level setWindowFlags(Qt::WindowStaysOnTopHint); // create connection object client = new QTcpSocket(this); //client = new QTcpServer(this); //Signal slot for connection status detection connect(client,SIGNAL(connected()),this,SLOT(connectedSlot())); connect(client,SIGNAL(disconnected()),this,SLOT(diaconnectedSlot())); connect(client,SIGNAL(readyRead()),this,SLOT(readReadSlot())); } Dialog::~Dialog() { // If the client is still connected, close it if(client->isOpen()){ client->close(); } delete ui; } void Dialog::btnConnClickedSlot(){ //The default input is valid, connect to the server //Parameter 1: IP address of the server //Parameter 2: The port number of the server client->connectToHost(ui->lineEditIp->text(),8887); } void Dialog::btnSendClickedSlot(){ // Get the content entered by the user QString msg = ui->lineEditMsg->text(); if(msg == ""){ QMessageBox::warning(this,"Prompt","Please enter the content to be sent!"); return; } //Create a text stream object QTextStream output(client); //Send Content output << msg; //clear the input box ui->lineEditMsg->clear(); QString time = QDateTime::currentDateTime().toString("hh:mm:ss"); ui->textBrowser->append(time); ui->textBrowser->append("Client:"); ui->textBrowser->append(msg); ui->textBrowser->append(""); } void Dialog::connectedSlot() { //shield connect button ui->pushButtonConn->setEnabled(false); ui->pushButtonConn->setText("connected"); //Release the send button ui->pushButtonSend->setEnabled(true); } void Dialog::diaconnectedSlot() { //Resume connection button ui->pushButtonConn->setEnabled(true); ui->pushButtonConn->setText("Connect!"); //block the send button ui->pushButtonSend->setEnabled(false); } void Dialog::readReadSlot(){ QString time = QDateTime::currentDateTime().toString("hh:mm:ss"); ui->textBrowser->append(time); QTextStream input(client); QString msg = input. readAll(); ui->textBrowser->append("Server:"); ui->textBrowser->append(msg); ui->textBrowser->append(""); }
ui interface
Server: (QTcpServer)
① Create a QTcpServer object
②The parameters required to monitor the list are address and port number
③When a new client connects successfully, send a newConnect signal
④In the newConnection signal slot function, call the nextPendingConnection function to obtain the new connection QTcpSocket object
⑤Connect to the readRead signal of the QTcpSocket object
⑥Use read to receive data in the slot function of the readRead signal
⑦Call the write member function to send data
dialog.h
#ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include <QtWidgets> //Network related classes #include <QTcpServer> #include <QTcpSocket> #include <QDateTime> #include <QTextStream> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); private: Ui::Dialog *ui; // management class server object QTcpServer *server; QTcpSocket*socket = NULL; // During the simple period, only one client connection is reserved private slots: //Slot function for new connection establishment void newConnSlot(); //Slot function for network connection disconnection void disconnectedSlot(); //Slot function to read information void readReadSlot(); void btnSendClickSlot(); }; #endif // DIALOG_H
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); // Set the window flag, always displayed in the foreground setWindowFlags(Qt::WindowStaysOnTopHint); // Create management class object server = new QTcpServer(this); //server = new QTcpSocket(this); //Connect to the signal slot notified by the server connect(server,SIGNAL(newConnection()),this,SLOT(newConnSlot())); // Turn on monitoring and wait for the client to initiate a connection //Parameter 1: Listen to the request from which IP address, the default value is not limited to the IP address //QHostAddress class is the encapsulation class of ip address //parameter 2: server port number server->listen(QHostAddress::Any,8887); } Dialog::~Dialog() { if(server->isListening()) // if listening // close the server server->close(); delete ui; } void Dialog::newConnSlot() { //If it is not the first connection, kick off the previous connection first if(socket!=NULL){ socket->close(); } //Get the QTcpSocket object connected to the client (green egg) socket = server->nextPendingConnection(); / / Create a signal slot for disconnection notification connect(socket,SIGNAL(disconnected()),this,SLOT(disconnectedSlot())); //Create a signal slot for reading messages connect(socket,SIGNAL(readyRead()),this,SLOT(readReadSlot())); connect(ui->pushButtonSend,SIGNAL(clicked()),this,SLOT(btnSendClickSlot())); //Get the IP and port number of the opposite client QString ip = socket->peerAddress().toString(); quint16 port = socket->peerPort(); // output information QString time = QDateTime::currentDateTime().toString("hh:mm:ss"); ui->textBrowser->append(time); ui->textBrowser->append("A new connection is coming!"); ui->textBrowser->append(ip.append(":").append(QString::number(port))); ui->textBrowser->append(""); } void Dialog::disconnectedSlot() { //Get the IP and port number of the opposite client QString ip = socket->peerAddress().toString(); quint16 port = socket->peerPort(); // output information QString time = QDateTime::currentDateTime().toString("hh:mm:ss"); ui->textBrowser->append(time); ui->textBrowser->append("The old connection is gone!"); ui->textBrowser->append(ip.append(":").append(QString::number(port))); ui->textBrowser->append(""); } void Dialog::readReadSlot() { QString time = QDateTime::currentDateTime().toString("hh:mm:ss"); ui->textBrowser->append(time); QTextStream input(socket); // read data QString msg = input. readAll(); //exhibit ui->textBrowser->append("Client:"); ui->textBrowser->append(msg); ui->textBrowser->append(""); } void Dialog::btnSendClickSlot() { QString msg2 = ui->lineEditMsg->text(); if(msg2 == ""){ QMessageBox::warning(this,"Prompt","Please enter the content to be sent!"); return; } QTextStream output(socket); output << msg2; ui->lineEditMsg->clear(); QString time = QDateTime::currentDateTime().toString("hh:mm:ss"); ui->textBrowser->append(time); ui->textBrowser->append("Server:"); ui->textBrowser->append(msg2); ui->textBrowser->append(""); }
ui interface
operation result: