先上效果圖
1. 圖中樣式我采用了qss 總體設計, 然後對每個按鈕進行單個設計
2. 使用 "控件提升", 為清單添加删除功能
2. 用戶端可以監視多個用戶端, 可以群發和單發
3. 輸入框使用 "eventFilter" , 來使用 "回車" 發送消息
一、 伺服器端
1. 在 .pro 檔案中添加 QT += core gui network
2. 定義:
private:
Ui::MainWindow *ui;
QTcpSocket * tcpClientSocket; // 用戶端套接字
QTcpServer * tcpServer; // 伺服器端對象
QList<QTcpSocket *> clientList; // 使用者連接配接表
3 . new 出tcpServer . 添加信号和槽: connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnectClient()));
tcpServer = new QTcpServer(this);
ui->server_ip->setText(get_localmachine_ip()); // 擷取本機的IP位址
ui->port_lineEdit->setText(tr("666"));
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnectClient())); // 建立連接配接
4. newConnectClient函數用來儲存新的連接配接, 并添加"讀"和"斷開" 的處理函數
void MainWindow::newConnectClient()
{
tcpClientSocket = tcpServer->nextPendingConnection(); //擷取網絡套接字
clientList.append(tcpClientSocket); // 儲存連接配接的Socket
QString strIP =tr("%1 : %2").arg(tcpClientSocket->peerAddress().toString().split("::ffff:")[1]).arg(
tcpClientSocket->peerPort()); // 拼接字元串
ui->connect_listWidget->addItem(strIP);
ui->IP_comboBox->addItem(strIP);
connect(tcpClientSocket,SIGNAL(readyRead()),this,SLOT(readData())); // 讀取用戶端發送的資訊
connect(tcpClientSocket,SIGNAL(error(QAbstractSocket::SocketError)),\
this,SLOT(readError(QAbstractSocket::SocetError)));
connect(tcpClientSocket,SIGNAL(disconnected()),this,SLOT(disconnectedSlot())); // 斷開連接配接
}
5. 點選監聽按鈕,開始監聽用戶端的請求:
try {
bool ok = tcpServer->listen(QHostAddress::Any,ui->port_lineEdit->text().toInt());
if(ok)
{
ui->statusBar->showMessage("開始監聽");
ui->connect_Button->setText("斷開");
ui->connect_Button->setStyleSheet("QPushButton{background-color: rgb(124, 200, 78);color:red;}"
"QPushButton:pressed{background-color:rgb(85, 170, 255); color:red;}");
}
} catch(QAbstractSocket::SocketError e){
readError(e);
}
6. 讀取資料使用
void MainWindow::readData()
{
foreach(QTcpSocket *socket, clientList){
QByteArray data = socket->readAll();
if(!data.isEmpty())
{
ui->show_textEdit->append(QString(data));
}
}
}
7. 發送資料
// 發送
void MainWindow::on_send_button_clicked()
{
QString data = ui->send_textEdit->toPlainText();
if (!data.isEmpty())
{
if (!ui->IP_comboBox->currentText().isEmpty())
{
// qDebug() <<ui->IP_comboBox->currentText();
// qDebug() << ui->IP_comboBox->itemText(0);
// qDebug() << ui->IP_comboBox->currentIndex();
QString clientIP = ui->IP_comboBox->currentText().split(":")[0].trimmed();
int clientPort = ui->IP_comboBox->currentText().split(":")
[1].trimmed().toInt();
// qDebug() << "ip " <<clientIP;
// qDebug() << clientPort;
foreach(QTcpSocket *socket,clientList)
{
if(socket->isValid())
{
if (socket->peerAddress().toString().split("::ffff:")[1] == clientIP &&
socket->peerPort() == clientPort)
{
int sendRe = socket->write(data.toUtf8().data());
ui->send_textEdit->clear();
}
}
}
}
}
}
二、用戶端:
1. 定義socket
private:
Ui::MainWindow *ui;
QTcpSocket *clientSocket;
2. 設定要連接配接的伺服器IP和端口
this->setWindowTitle(tr("用戶端"));
this->setFixedSize(750,600);
ui->statusBar->showMessage(tr("未連接配接伺服器"));
ui->server_ip->setText("192.168.1.3");
ui->port_lineEdit->setText("666");
3. 連接配接伺服器, 注意ip位址需要用 “QHostAddress” 進行轉換, 直接用ip無法連接配接 , 連接配接成功添加 “讀” 和“删除” 信号
if (ui->connect_Button->text() == "連接配接")
{
this->clientSocket = new QTcpSocket(this);
QString ip = ui->server_ip->text().trimmed();
QHostAddress * addtress = new QHostAddress;
addtress->setAddress(ip);
short port = ui->port_lineEdit->text().toShort();
this->clientSocket->connectToHost(*addtress,port);
connect(clientSocket,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));
connect(clientSocket,SIGNAL(disconnected()),this,SLOT(disconnectedSlots()));
}
4. 讀取和發送和伺服器一樣
源碼位址: https://download.csdn.net/download/chen1231985111/10872106