Qt TCP/IP网络编程

在qt中的网络编程和之前在windows中的网络编程的基本步骤是一样的,服务器有两个套接字,一个负责监听(QTcpServer),还有一个负责通信(QTcpSocket),客户端只有一个负责通信的套接字(QTcpSocket)。

服务器和客户端通信的基本步骤

1、QTcpServer对象负责监听是否有客户端连接此服务器。它是通过这样一个函数监听的

 tcpserver->listen(QHostAddress::Any, 8888);

它的第一个参数表示服务器监听的地址,如果后面是Any表示监听本机的所有网口的,第二个参数表示监听的网络端口。

2、如果服务器监听到有客户端和它进行连接,服务器就会触发newConnection这个信号。同时客户端一旦和服务器连接成功,客户端会触发connected这个信号,表示已经成功和服务器连接。

3、在两者建立好连接之后,服务器需要返回一个QTcpSocket对象来和客户端进行通信,通常通过这个函数来返回一个建立好连接的套接字。

tcpsocket = tcpserver->nextPendingConnection();

4、接着就可以通过两这的通信套接字来完成通信。当一端发送成功之后,接收方会触发这么一个信号,readyRead,这样我们就能够读取套接字当中的内容了。

5、断开连接的时候我们使用这样的函数

tcpsocket->disconnectFromHost();

现在我们就通过Qt Creator来实现客户端和服务器进行通信。

一、服务器端

首先我们先建立一个项目,名字叫tcpserver,它的基类是QWidget。这次我们使用Qtdesigner界面设计器,所以我们勾选创建图形界面。并且将其布好局。如下图所示。

首先给监听套接字分配空间,并指定父对象。然后让其监听

1 tcpserver = new QTcpServer(this);
2 tcpserver->listen(QHostAddress::Any, 8888);

一旦监听到由客户端和其连接,就会触发newConnection这个信号,我们需要创建一个槽函数来实现和客户端的连接之后的操作。接着我们需要将这个信号和我们写的槽函数进行绑定。

1 tcpserver = new QTcpServer(this);
2 tcpserver->listen(QHostAddress::Any, 8888);
3 connect(tcpserver, &QTcpServer::newConnection, this, &Widget::ConnectToClient);

上面的ConnectToClient是用来处理连接后的一些操作的槽函数。

连接完成之后,我们可以将客户端的IP地址和端口号显示在文本编辑框中。这个时候我们就需要用到通信套接字,上面我们也说过通信套接字,是通过这个函数来返回的tcpserver->nextPendingConnection()。

1 //取出建立好的套接字
2 tcpsocket = tcpserver->nextPendingConnection();
3 //获取对方的端口号和ip地址,并且显示在文本编辑框中。
4 QString ip = tcpsocket->peerAddress().toString();
5 qint16 port = tcpsocket->peerPort();
6  
7 ui->textEditRead->setText(QString("[%1:%2]连接成功").arg(ip).arg(port));

接着我们就可以和客户端进行通信了。这里我们ui中右击“发送”按钮,然后转到槽,这样qtcreator就会自动给我们将这个按钮和相应的槽函数绑定起来。接着我们只需要在它给我们创建好的槽函数中编写通信的代码就可以了。

1 QString str = ui->textEditWrite->toPlainText();
2 tcpsocket->write(str.toUtf8().data());

上面的代码就是获取文本编辑框中的内容,然后通过通信套接字来发送数据的,发送的时候我们用write这个函数,它的一种重载形式就是将其转为char* 类型的数据,然后发送。我们这里就用这种形式。

发送完成之后,客户端会触发这样的一个信号:readyRead,然后我们将这个信号和处理这个信号的槽函数绑定(这个槽函数需要我们自己编写)。

绑定的过程

connect(tcpsocket, &QTcpSocket::readyRead, this, &Widget::ReadInformation);

读取套接字中的内容,并将其显示在文本编辑框中

1 void Widget::ReadInformation()
2 {
3     //获取套接字中的内容
4     QByteArray temp = tcpsocket->readAll();
5     ui->textEditRead->append(temp);
6 }

读取套接字中的内容有很多种方式,这里我们使用readAll()这个函数,这个函数需要返回这样一个QByteArray一个对象,所我们就使用这个对象来记录套接字中的内容,然后显示出来就行了。

最后断开连接,我们也使用界面上的按钮来断开。右击转到槽就行,接下来我们只需要将tcpsocket和客户端的断开就行了

1 void Widget::on_pushButtonClose_clicked()
2 {
3     tcpsocket->disconnectFromHost();//主动和客户端断开连接
4     tcpsocket->close();
5     tcpsocket = NULL;
6 }

二、客户端

首先我们也创建一个项目,过程和服务器端相同,客户端比较简单,只有一个通信套接字。

创建项目之后我们需要使用Qt designer来布局如下图所示

我们先给tcpsocket初始化,并且指定父对象。我们需要使用连接按钮来连接服务器,相同的步骤,右击转到槽。

然后我们在它给我们函数中编辑我们的连接代码,首先需要获取需要连接的端口号和IP地址,然后使用tcpsocket->connectToHost((QHostAddress)ip, port);这个函数来和服务器进行连接。

connectToHost()这个函数的第一个参数是IP地址,但是他的类型是QHostAddress,所以我们需要将从界面中获取的ip地址的类型进行一下转换,第二个参数是对方的端口号。

1 void Widget::on_pushButtonConnect_clicked()
2 {
3     QString ip = ui->lineEditIpAddress->text();
4     qint16 port = ui->lineEditPort->text().toInt();
5  
6     //主动和服务器进行连接
7     tcpsocket->connectToHost((QHostAddress)ip, port);
8 }

连接成功之后客户端会触发这样一个信号 connected,当触发这个信号我们可以在客户端中显示连接成功的字样,告诉客户我们连接成功。我们需要将这个信号和自己写的用来处理这个信号的函数进行绑定。

绑定的过程如下

connect(tcpsocket, &QTcpSocket::connected, this, &Widget::connectToServer);

将连接成功的字样写实在文本编辑框中

1 void Widget::connectToServer()
2 {
3     ui->textEditRead->setText("成功和服务器进行连接");
4 }

然后就可以发送和接收了,这两个代码和服务器的相同,就不写了,关闭的代码也是一样的。只不过我们在客户端中不需要将这个套接字关闭掉,防止断开连接之后,不能再次连接上。

最后我们运行这两个程序,结果是这样的。

原文地址:https://www.cnblogs.com/ybqjymy/p/13684116.html