qt 实现简单聊天(一个服务器和多个客服端)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt 实现简单聊天(一个服务器和多个客服端)相关的知识,希望对你有一定的参考价值。
源码地址:https://github.com/haidragon/easyChat思路 :
-
一个服务器一直接听某个 ip 的某个端口
listen(QHostAddress::Any,port);
2.一个服务器有一个容器保存所有各客服端的链接(每个链接都是一个类)。QList<TcpClientSocket> tcpClientSocketList;每当一个客服端链接上那个服务器一直接听的套节字时。服务器会自动调用一个函数。incomingConnection(qintptr socketDescriptor);(这个函数是继承过来的虚函数)
3.每次调用链接函数时 new 一个新的客服端流(也就是另外增加一个类。这个类就是客服端流类)TcpClientSocket tcpClientSocket=new TcpClientSocket(this);
4.服务器管理所有的服端流。
5.每次新创建一个客服端流时会往流里写入链接成功的数据。//链接后就往套节字里发内容 void TcpClient::slotConnected() { sendBtn->setEnabled(true); enterBtn->setText(tr("离开")); int length=0; QString msg=userName+tr(":Enter Chat Room"); if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length()) { return; } }
6.由于每个客服端流是分开的只有服务器能够知道所有流里的数据。因此每当有客服端流中有数据时在服务器中会发给其它客服端流。其它客服端流只要流中有数据会一直更新。实现了简单群聊。
void Server::updateClients(QString msg,int length) { emit updateServer(msg,length); //这里是往每个链接里与 for(int i=0;i<tcpClientSocketList.count();i++) { QTcpSocket *item = tcpClientSocketList.at(i); if(item->write(msg.toLatin1(),length)!=length) { continue; } } }
7.服务器端也实现了 ui 见面
8.每个客服端只要断开链接。它就会在这个流中发一个断开信号。因为服务器保存了每个客服端的流。当某个客服端流断开时会发一个断开信号同时带上标志。服务器只要检测到了这个信号会及时处理。else { int length=0; QString msg=userName+tr(":Leave Chat Room"); if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg. length()) { return; } tcpSocket->disconnectFromHost(); status=false; } ///////// tcpclientsocket类 void TcpClientSocket::slotDisconnected() { emit disconnected(this->socketDescriptor()); } ///server类 void Server::slotDisconnected(int descriptor) { for(int i=0;i<tcpClientSocketList.count();i++) { QTcpSocket *item = tcpClientSocketList.at(i); if(item->socketDescriptor()==descriptor) { tcpClientSocketList.removeAt(i); return; } } return; }
以上是关于qt 实现简单聊天(一个服务器和多个客服端)的主要内容,如果未能解决你的问题,请参考以下文章
使用 WPF + Chrome 内核实现 在线客服系统 的复合客服端程序