Qt 局域网聊天

TCP (Transmission Control Protocol) 传输控制协议 . 面向连接和数据流的可靠传输协议 .

使用的是客户端 / 服务器模式 ….

 

QT QTcpSocket 来编写客户端程序 , QTcpServer 来编写服务器端程序 ….

 

我们通过 QTcpServer listen(QHostAddress::Any,port) 函数来进行端口的监听 , 一旦发现客户端的连接请求 , 就会发出 newConnection() 信号 这样绑定上相应的槽函数就可以进行数据的发送了 ….

 

客户端 QTcpSocket 一旦有数据到来就会发出 readyRead() 信号 , 我们可以关联此信号进行数据的接收

 

Tcp 连接示例图 :

下面举一个小例子 , 来实现服务器端到客户端的连接

 

服务器端的实现 :

 

 

// Client.cpp 继承自 QTcpStock // 自定义信号槽 connect (this , SIGNAL (readyRead ()),this , SLOT (dataReceived ())); connect (this , SIGNAL (disconnected ()),this , SLOT (slotDisconnected ())); void Client ::dataReceived () { while (bytesAvailable ()>0) { char buf [1024]; int length =bytesAvailable (); read (buf , length ); QString msg =buf ; emit updateClients (msg ,length ); } } void Client ::slotDisconnected () { emit disconnected (this ->socketDescriptor ()); }  // Server.cpp 继承自 QTcpServer // 首先需要重写 QTcpServer 的 incomingConnection( int socketDescriptor ) 函数 void Server ::incomingConnection ( int socketDescriptor ) { Client *tcpClientSocket = new Client (this ); connect (tcpClientSocket ,SIGNAL (updateClients (QString ,int )),this ,SLOT (updateClients (QString ,int ))); connect (tcpClientSocket ,SIGNAL (disconnected (int )),this ,SLOT (slotDisconnected (int ))); tcpClientSocket ->setSocketDescriptor (socketDescriptor ); tcpClientSocketList .append (tcpClientSocket ); } // 在接收到客户端发送的消息时会触发这个槽函数 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 ; } } } // 客户端断开连接时 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 ; }

// tcpServer.cpp // 创建连接 QTcpServer *tcpServer_ = new QTcpServer(); if(!tcpServer_->listen(QHostAddress::Any,8010)) { qDebug()<< tcpServer_->errorString(); tcpServer_->close(); } else { qDebug()<<"Listen Success!"; } // 这里自定义消息 updateServer(QString,int) 用来接收有客户端连接时的通知 ... connect(tcpServer_,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int))); // 显示接到的客户端发送的消息 void tcpServer ::updateServer ( QString msg ,int length ) { textEdit_Display ->append (msg .left (length ) ); }

 

 

客户端的实现 :

 

// tcpClient.cpp // 创建连接 tcpSocket_ = new QTcpSocket (this ); tcpSocket_ ->abort (); // 取消已有的连接 tcpSocket_ ->connectToHost ("192.168.1.21" ,88888); // 连接到主机,这里从界面获取主机地址和端口号 connect (tcpSocket_ ,SIGNAL (readyRead ()),this ,SLOT (readMessage ())); connect (tcpSocket_ ,SIGNAL (error (QAbstractSocket ::SocketError )), this ,SLOT (displayError (QAbstractSocket ::SocketError ))); // 发送消息 void tcpClient ::solt_sendMessage () { if (textEdit_Input ->toPlainText ()=="" ) { return ; } QString msg = textEdit_Input ->toPlainText (); tcpSocket_ ->write (msg .toLatin1 (),msg .length ()); textEdit_Input ->clear (); } // 显示接收到数据 void tcpClient ::readMessage () { //// 显示接收到的数据 while (tcpSocket_ ->bytesAvailable ()>0) { QByteArray datagram ; datagram .resize (tcpSocket_ ->bytesAvailable ()); QHostAddress sender ; tcpSocket_ ->read (datagram .data (), datagram .size ()); QString msg =datagram .data (); textEdit_Display ->append (msg .left (datagram .size ())); } } // 输出错误消息 void tcpClient ::displayError (QAbstractSocket ::SocketError ) { qDebug ()<<tcpSocket_ ->errorString (); // 输出错误信息 } 

 

QTcpServer  QTcpStock 之间的工作原理是这样的 ...

首先由 QTcpServer 创建 一个监听 listen(hostAddress,port) ...  这样就对此 prot 进行了监听 ....

 

然后启动客户端的连接 connectToHost(hostAddress,port).... 当服务器端接收到 客户端的连接时 , 首先会触发 QTcpServer

incomingConnection( int socketDescriptor )  消息 ... 这时就可以将当前连接的客户端的 ID 号加入到服务器端的客户端列表里进行维护了 ...( 不知道这样理解对不对 ???)

 

当客户端发送消息到服务器端时 .. 就会触发 QTcpServer updateClients() 消息 ... 然后服务器通过发送 updateServer() 消息通知服务器端更新信息 ... 然后再通过已有的客户端列表 , 向已连接的客户端写回信息 ... 这时就会触发客户端的 readMessage() 函数 ... 将接收到的消息显示在客户端 ...

 

Qt 局域网聊天_第1张图片 Qt 局域网聊天_第2张图片

你可能感兴趣的:(服务器,input,qt,聊天,Signal,Descriptor)