一、TCP的特点

TCP(传输控制协议)是一种面向连接的,可靠的,基于字节流的传输层通信协议

二、TCP适合应用的场景

TCP协议适用于要求可靠传输的应用,例如文件传输,网络数据库,分布式高精度计算系统的数据传输。

三、Qt中使用TCP通信

Qt中的TCP通信与之前所讲的UDP通信有着明显区别,使用TCP通信,就有着明确的客户端与服务器之分,服务器有两个套接字,分别是一个用于通信的通信套接字(QTcpSocket),一个是用于监听的监听套接字(QTcpServer),客户端只有一个用于通信的通信套接字(QTcpSocket),基本流程是客户端首先得向服务器发送连接请求,服务器监听到有客户端向它发送连接请求时,会触发newConnection信号,与此同时,客户端会触发connected信号,表示与服务器成功连接,两者建立好连接之后,服务器需要返回一个通信套接字用于和客户端通信,随后客户端与服务器就可以通过通信套接字来进行数据之间的通信

四、客户端与服务器通信的实现

添加网络模块

QT += network;

添加头文件

#include<QTcpSocket> //通信套接字
#include<QTcpServer> //监听套接字

服务器端的实现

tcpserver分配空间,指定父对象,然后开始监听

tcpserver = new QTcpServer(this); //分配空间,指定父对象
tcpserver->listen(QHostAddress::Any,8888);//监听本机所有网口及8888端口号

一旦监听到有客户端发起了连接请求,服务器端触发newConnection信号,与此同时,客户端会触发connected信号,服务器返回一个建立好连接的通信套接字,当客户端发送数据时,服务器端会触发readyRead信号,取出tcpsocket中的数据,显示到窗口中,实现接收数据

客户端返回一个建立好连接的通信套接字一般使用如下函数

tcpsocket = tcpserver->nextPendingConnection();

 完整代码

connect(tcpserver,&QTcpServer::newConnection,[=] //Server监听到连接请求触发newConnection信号
    {
        tcpsocket = tcpserver->nextPendingConnection();//Client与Server建立连接后,Server返回一个建立好连接用于通信的套接字
        QString ip = tcpsocket->peerAddress().toString();//获取对方的IP
        qint16 port = tcpsocket->peerPort();//获取对方的端口
        QString time= QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");//获取当前时间
        ui->te_output->append(time+"\n"+QString("成功与[%1:%2]建立连接...").arg(ip).arg(port));

        connect(tcpsocket,&QTcpSocket::readyRead,[=] //接收数据
        {
            QString message = tcpsocket->readAll();
           QString time= QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
           ui->te_output->append(time + "\n"+message);
        });
    });

发送数据,使用write()函数,因为已经建立好了连接,所以参数可以只有一个,就是你想发送的数据

//获取用户输入的信息
    QString text = ui->te_input->toPlainText();
    tcpsocket->write(text.toUtf8().data());

断开连接,使用disconnectFromHost();

tcpsocket->disconnectFromHost();//主动和客户端断开连接
tcpsocket->close();
tcpsocket = NULL;

客户端的实现

客户端向服务器发送连接请求

第一个参数是服务器的IP地址,第二个参数是服务器的端口号

tcpsocket->connectToHost(QHostAddress(peerip),peerport);

客户端成功连接服务器,触发connected信号,触发相应槽函数

connect(tcpsocket,&QTcpSocket::connected,[=] //客户端成功建立连接后触发connected信号
    {
        QString str = QString("成功与[%1:%2]建立连接...").arg(peerip).arg(peerport);
        QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        ui->te_output->append(time+"\n"+str);
    });

客户端的发送与接收数据与服务器端是相同的,就不再过多阐述了

发送数据

//获取用户输入的信息
QString text = ui->te_input->toPlainText();
tcpsocket->write(text.toUtf8().data());

接收数据

connect(tcpsocket,&QTcpSocket::readyRead,[=]
    {
       QString message = tcpsocket->readAll();
       QString time= QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
       QString name = tcpsocket->peerName();
       ui->te_output->append(time + "\n"+name+":"+message);
    });

断开连接时tcpsocket会触发disconnected信号

connect(tcpsocket,&QTcpSocket::disconnected,[=]
    {
        QString time= QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        ui->te_output->append(time + "\n"+"与服务器断开连接...");
    });

程序演示

建立连接

QT 网络通信 rpc_QT 网络通信 rpc

 互相发送数据

QT 网络通信 rpc_客户端_02

断开连接

QT 网络通信 rpc_tcp/ip_03

 

客户端与服务器端都可以主动与对方断开连接,断开连接后,双方就不能进行通信了

我是龙木南,这篇文章对你有帮助的话~就点个赞把~

点赞关注收藏就是对我最大的支持~