1、服务端程序
利用QtCreator新建QMainWindow或QWidget工程,绘制UI如下所示。
mainwindow.h代码如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QList>
#define MAXNUM (9)
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QTcpServer* myServer;
QTcpSocket* myClient;
QList<QTcpSocket*> arrayClient;
private slots:
void on_pushButtonServerSet_clicked();
void doProcessNewConnection();
void doProcessDiconnected();
void doProcessReadyRead();
void on_pushButtonClientSend_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("TCP服务端程序");
myServer = new QTcpServer(this);
myClient = new QTcpSocket(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButtonServerSet_clicked()
{
QString myAddr;
//手动设置ip
myAddr = ui->lineEditServerIP->text();
QString myPort = ui->lineEditServerPort->text();
QString msg;
bool ret = myServer->listen(QHostAddress(myAddr),myPort.toUInt());
if(!ret) {
msg = "绑定失败";
} else {
msg = "绑定成功";
ui->pushButtonServerSet->setEnabled(false);
}
ui->textEditServer->append(msg);
myServer->setMaxPendingConnections(MAXNUM);
connect(myServer,SIGNAL(newConnection()),this,SLOT(doProcessNewConnection()));
connect(myServer,SIGNAL(acceptError(QAbstractSocket::SocketError)),
this,SLOT(doProcessAcceptError(QAbstractSocket::SocketError)));
}
void MainWindow::on_pushButtonClientSend_clicked()
{
QString ip = ui->lineEditClientIP->text();
QString port = ui->lineEditClientPort->text();
//查找对应的客户
for(int i=0;i<arrayClient.length();i++)
{
if(arrayClient.at(i)->peerAddress().toString()==ip)
{
if(arrayClient.at(i)->peerPort() == port.toUInt())
{
QString msg = ui->textEditClient->toPlainText();\
arrayClient.at(i)->write(msg.toUtf8());
ui->textEditClient->clear();
break;
}
}
}
}
void MainWindow::doProcessNewConnection()
{
myClient = myServer->nextPendingConnection();
arrayClient.append(myClient);
QString msg = QString("客户端[%1:%2] 连入!")
.arg(myClient->peerAddress().toString())
.arg(myClient->peerPort());
ui->textEditServer->append(msg);
//客户端断开
connect(myClient,SIGNAL(diconnected()),this,SLOT(doProcessDiconnected()));
//读取内容
connect(myClient,SIGNAL(readyRead()),this,SLOT(doProcessReadyRead()));
}
void MainWindow::doProcessDiconnected()
{
QTcpSocket *client = (QTcpSocket *)this->sender();
QString msg = QString("客户端[%1:%2] 退出!")
.arg(client->peerAddress().toString())
.arg(client->peerPort());
ui->textEditServer->append(msg);
//删除对应客户端
for(int i= 0;i<arrayClient.length();i++)
{
if(arrayClient.at(i)->peerAddress() == client->peerAddress())
{
if(arrayClient.at(i)->peerPort() == client->peerPort())
{
arrayClient.removeAt(i);
break;
}
}
}
}
void MainWindow::doProcessReadyRead()
{
QTcpSocket *client = (QTcpSocket *)this->sender();
QString str1 = QString(QString("客户端[%1:%2] 说:")
.arg(client->peerAddress().toString())
.arg(client->peerPort()));
QString msg;
QString str2;
while (!client->atEnd())
{
msg.append(QString(client->readAll()));
}
str2 = QString("%1%2").arg(str1).arg(msg);
ui->textEditServer->append(str2);
}
2、客户端程序
利用QtCreator新建QWidget或QMainWindow工程,绘制UI如下所示。
widget.h代码如下:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
QTcpSocket* myClient;
private slots:
void on_pushButtonConnect_clicked();
void on_pushButtonSend_clicked();
void dorProcessReadyRead();
void doProcessConnected();
void doProcessDisconnected();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp代码如下:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("TCP客户端程序");
myClient = new QTcpSocket(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButtonConnect_clicked()
{
QString servIp = ui->lineEditIP->text();
QString servPort = ui->lineEditPort->text();
myClient->connectToHost(QHostAddress(servIp),servPort.toUInt());
//myClient->connectToHost(servIp,servPort.toShort());
connect(myClient,SIGNAL(connected()),this,SLOT(doProcessConnected()));
connect(myClient,SIGNAL(readyRead()),this,SLOT(dorProcessReadyRead()));
connect(myClient,SIGNAL(disconnected()),this,SLOT(doProcessDisconnected()));
// connect(myClient,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(doProcessError(QAbstractSocket::SocketError)));
}
void Widget::on_pushButtonSend_clicked()
{
QString msg = ui->textEdit_2->toPlainText();
int ret = myClient->write(msg.toUtf8());
if(ret<=0)
return;
ui->textEdit_2->clear();
}
void Widget::doProcessConnected()
{
ui->textEdit->append("服务器连接成功!");
}
void Widget::doProcessDisconnected()
{
ui->textEdit->append("服务器断开连接!");
}
void Widget::dorProcessReadyRead()
{
QString msg,str1,str2;
str1 = QString(" 服务器[%1:%2] 说:")
.arg(myClient->peerAddress().toString())
.arg(myClient->peerPort());
while(!myClient->atEnd())
{
str2.append(QString(myClient->readAll()));
}
msg = QString("%1%2").arg(str1).arg(str2);
ui->textEdit->append(msg);
}
3、运行示例
先后编译运行服务端和客户端。
在服务端中输入IP和端口号然后点击绑定按钮,绑定成功后,在客户端输入服务端的IP和端口后点击连接按钮。连接成功,在客服端发送信息,服务端收到后,可填入客户端的IP和Port回复信息给客户端。
运行示意图如下。