欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

QT的TCP协议

程序员文章站 2022-07-10 13:54:34
...

客户端:

IP地址 :QString 

端口号:int

设置服务器主机地址:QHostAddress::setAddress(IP地址)

TCP套接字 用来接收和发送数据的 QTcpSocket

与主机连接: QTcpSocket::connectToHost(服务器主机地址,端口号)

QTcpSocket

与主机连接成功:  [signal] void connected()

QString msg=userName+":"+sendLineEdit->text(); 
//格式转换 
QByteArray data = msg.toUtf8(); 
//传给服务端
 QTcpSocket::write(data,data.length());

与主机断开连接才会调用触发: [signal] void disconnected()

当收到消息时发送该信号触发: [signal] void readyRead()

1.	//bytesAvailable返回接收到的数据的长度  
2.	    while(QTcpSocket::bytesAvailable()>0)  
3.	    {  
4.	        //有数据可读取  
5.	        QByteArray datagram;  
6.	          
7.	        //设置字节大小  
8.	        datagram.resize(QTcpSocket::bytesAvailable());  
9.	        //套接字读取  
10.	        QTcpSocket::read(datagram.data(),datagram.size());  
11.	  
12.	        //格式转换  
13.	        QString msg=QString::fromUtf8(datagram);  
14.	    }  

连接出错触发:  [signal] error(QAbstractSocket::SgocketError)

1.	//槽函数接收错误信息  
2.	void TcpClient::onError(QAbstractSocket::SocketError socketError)  
3.	{  
4.	    QString str;  
5.	  
6.	    switch(socketError){  
7.	        case QAbstractSocket::ConnectionRefusedError:  
8.	            str = tr("服务器连接被拒绝或者连接超时。错误代码:%1").arg(socketError);  
9.	            break;  
10.	        case QAbstractSocket::RemoteHostClosedError:  
11.	            str = tr("远程主机关闭。错误代码:%1").arg(socketError);  
12.	            break;  
13.	        case QAbstractSocket::HostNotFoundError:  
14.	            str = tr("远程主机未找到。错误代码:%1").arg(socketError);  
15.	            break;  
16.	        default:  
17.	            str = tr("未知错误。错误代码:%1").arg(socketError);  
18.	            break;  
19.	    }  
20.	    status = false;  
21.	    QMessageBox::information(this,tr("错误提示"),str);  
22.	}  

断开主机连接

23.	//断开连接  
24.	int length=0;  
25.	QString msg=userName+tr(":离开聊天室");  
26.	  
27.	QByteArray data = msg.toUtf8();  
28.	  
29.	if((length=tcpSocket->write(data,data.length()))!=data. length())  
30.	{  
31.	    return;  
32.	}  
33.	//当前连接的主机断开  
34.	tcpSocket->disconnectFromHost();  

服务端:

pro配置文件中引入

1.	TARGET = TcpServer  
2.	TEMPLATE = app  

提供一个基于TCP的服务,可以 指定端口或让自动选择一个端口:QTcpServer

Server  .h文件

3.	#include <QTcpServer>  
4.	#include <QObject>  
5.	#include "tcpclientsocket.h"  
6.	  
7.	/** 
8.	 * @brief The TcpServer class 
9.	 * 
10.	 * 1.监听端口,等待连接 
11.	 * 2.创建连接 
12.	 * 3.消息的分发 
13.	 * 4.客户端断开连接操作 
14.	 * 
15.	 */  
16.	class Server : public QTcpServer  
17.	{  
18.	    Q_OBJECT  
19.	public:  
20.	    Server(QObject *parent=0,int port=0);  
21.	  
22.	    //已连接套接字的容器,消息转发  
23.	    QList<TcpClientSocket*> tcpClientSocketList;  
24.	signals:  
25.	    //自定义信号,当有效性收到的时候,更新服务器显示  
26.	    void updateServer(QString,int);  
27.	public slots:  
28.	    //收到消息之后转发给所有的客户端  
29.	    void updateClients(QString,int);  
30.	    //客户端断开连接时,触发的槽  
31.	    void slotDisconnected(int);  
32.	protected:  
33.	    //有新的消息进来时,执行  
34.	    void incomingConnection(qintptr socketDescriptor) override;  
35.	};  

Server  .cpp文件  

重点(有新消息都会执行)重写方法:void incomingConnection(qintptr socketDescriptor) override;

36.	#include "server.h"  
37.	  
38.	Server::Server(QObject *parent,int port)  
39.	    :QTcpServer(parent)  
40.	{  
41.	    //监听端口,QHostAddress::Any 任意主机 ,port端口号  
42.	    listen(QHostAddress::Any,port);  
43.	}  
44.	//socketDescriptor 套接字标识符  
45.	void Server::incomingConnection(qintptr socketDescriptor)  
46.	{  
47.	    //有新的连接  
48.	    //初始化服务器端的套接字  
49.	    TcpClientSocket *tcpClientSocket=new TcpClientSocket(this);  
50.	    //消息分发  
51.	    connect(tcpClientSocket,SIGNAL(updateClients(QString,int)),this,SLOT(updateClients(QString,int)));  
52.	    //断开连接  
53.	    connect(tcpClientSocket,SIGNAL(disconnected(int)),this,SLOT(slotDisconnected(int)));  
54.	  
55.	    //设置当前套接字的唯一标识  
56.	    tcpClientSocket->setSocketDescriptor(socketDescriptor);  
57.	    //添加到容器  
58.	    tcpClientSocketList.append(tcpClientSocket);  
59.	}  
60.	  
61.	void Server::updateClients(QString msg,int length)  
62.	{  
63.	    //消息分发  
64.	    //将信息显示在客户端  
65.	    emit updateServer(msg,length);  
66.	  
67.	    //遍历所有的客户端套接字  
68.	    for(int i=0;i<tcpClientSocketList.count();i++)  
69.	    {  
70.	        QTcpSocket *item = tcpClientSocketList.at(i);  
71.	        QByteArray data = msg.toUtf8();  
72.	  
73.	        if(item->write(data,data.length())!=data.length())  
74.	        {  
75.	            continue;  
76.	        }  
77.	    }  
78.	}  
79.	  
80.	void Server::slotDisconnected(int descriptor)  
81.	{  
82.	    //移除断开连接的套接字  
83.	    for(int i=0;i<tcpClientSocketList.count();i++)  
84.	    {  
85.	        QTcpSocket *item = tcpClientSocketList.at(i);  
86.	  
87.	        //根据套接字标识进行唯一确定  
88.	        if(item->socketDescriptor()==descriptor)  
89.	        {  
90.	            tcpClientSocketList.removeAt(i);  
91.	            break;  
92.	        }  
93.	    }  
94.	}  

TCP套接字 用来接收和发送数据的: QTcpSocket

TcpClientSocket  .h文件

95.	#include <QTcpSocket>  
96.	#include <QObject>  
97.	  
98.	/** 
99.	 * @brief The TcpClientSocket class 
100.	 * 
101.	 * 将消息的处理放置在自定义套接字中,达到封装的效果 
102.	 * 
103.	 */  
104.	  
105.	class TcpClientSocket : public QTcpSocket  
106.	{  
107.	    Q_OBJECT  
108.	public:  
109.	    TcpClientSocket(QObject *parent=0);  
110.	signals:  
111.	    //接收到消息发送更新客户端的信号,告诉TCPServer去更新所有的客户端  
112.	    void updateClients(QString,int);  
113.	    //断开连接,参数:套接字的唯一标识符  
114.	    void disconnected(int);  
115.	protected slots:  
116.	    //数据处理  
117.	    void dataReceived();  
118.	    //断开连接  
119.	    void slotDisconnected();  
120.	};  

TcpClientSocket .cpp文件

121.	#include "tcpclientsocket.h"  
122.	  
123.	TcpClientSocket::TcpClientSocket(QObject *parent)  
124.	{  
125.	    //readyRead,有消息时的处理  
126.	    connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));  
127.	    //当客户端和服务器断开连接时  
128.	    connect(this,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));  
129.	}  
130.	  
131.	void TcpClientSocket::dataReceived()  
132.	{  
133.	    //返回接收到的数据的长度  
134.	    while(bytesAvailable()>0)  
135.	    {  
136.	        int length = bytesAvailable();  
137.	        QByteArray data = read(length);  
138.	        QString msg=QString::fromUtf8(data);  
139.	        //发射updateClients信号  
140.	        emit updateClients(msg,msg.length());  
141.	    }  
142.	}  
143.	  
144.	void TcpClientSocket::slotDisconnected()  
145.	{  
146.	    //发送连接断开的信号  
147.	    //socketDescriptor 每一个连接的套接字都会有一个唯一标识  
148.	    emit disconnected(this->socketDescriptor());  
149.	}  

主要触发的.cpp文件

150.	void TcpServer::slotCreateServer()  
151.	{  
152.	    //创建一个Server对象  
153.	    server = new Server(this,port);  
154.	    //更新服务器消息  
155.	    connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));  
156.	    //按钮不可点  
157.	    CreateBtn->setEnabled(false);  
158.	    ContentListWidget->addItem(tr("聊天室创建成功。。。"));  
159.	}  
160.	  
161.	void TcpServer::updateServer(QString msg,int length)  
162.	{  
163.	    //显示从客户端传来的消息  
164.	    ContentListWidget->addItem(msg.left(length));  
165.	}  

 

相关标签: QT C++