废话不多说,上演示效果
由于我们用到socket跟Lamda表达式,所以工程.pro文件需要添加对应的库
为了方便,main.cpp中让程序显示两个Widget窗口,程序运行起来就可以测试
ServerWidget w;
w.show();
ClientWidget w2;
w2.show();
一、服务端
服务端的UI界面布局:
2个PushButton(send,close)
2个textEdit(发送内容,接收内容)
新建一个监听套接字,监听端口号为9999的IP,等待连接,有连接过来提示成功连接同时服务端读就绪
//监听套接字,指定父对象,让其自动回收空间 tcpServer = new QTcpServer(this); tcpServer->listen(QHostAddress::Any, 9999); setWindowTitle("服务器: 9999"); //newConnection代表有新的连接 connect(tcpServer, &QTcpServer::newConnection, [=]() { //取出建立好连接的套接字 tcpSocket = tcpServer->nextPendingConnection(); //获取对方的IP和端口 QString ip = tcpSocket->peerAddress().toString(); quint16 port = tcpSocket->peerPort(); QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port); ui->textEditRead->setText(temp); //readyRead代表读就绪 connect(tcpSocket, &QTcpSocket::readyRead, [=]() { //从通信套接字中取出内容 QByteArray array = tcpSocket->readAll(); ui->textEditRead->append(array); } ); } );
二、客户端
客户端的UI界面布局:
3个PushButton(connect,send,close)
2个lineEdit(端口号,IP)
2个textEdit(发送内容,接收内容)
客户端连接按钮主动与服务端建立连接
void ClientWidget::on_buttonConnect_clicked() { //获取服务器ip和端口 QString ip = ui->lineEditIP->text(); qint16 port = ui->lineEditPort->text().toInt(); //主动和服务器建立连接 tcpSocket->connectToHost(QHostAddress(ip), port); }
连接成功后会触发connected,提示"成功和服务器建立好连接"同时客户端读就绪
//分配空间,指定父对象 tcpSocket = new QTcpSocket(this); setWindowTitle("客户端"); connect(tcpSocket, &QTcpSocket::connected, [=]() { ui->textEditRead->setText("成功和服务器建立好连接"); } ); connect(tcpSocket, &QTcpSocket::readyRead, [=]() { //获取对方发送的内容 QByteArray array = tcpSocket->readAll(); //追加到编辑区中 ui->textEditRead->append(array); } );
三、源码
main.cpp
#include "serverwidget.h" #include <QApplication> #include "clientwidget.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); ServerWidget w; w.show(); ClientWidget w2; w2.show(); return a.exec(); }
serverwidget.cpp
#include "serverwidget.h" #include "ui_serverwidget.h" #include <QDebug> ServerWidget::ServerWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ServerWidget) { ui->setupUi(this); tcpServer = NULL; tcpSocket = NULL; //监听套接字,指定父对象,让其自动回收空间 tcpServer = new QTcpServer(this); tcpServer->listen(QHostAddress::Any, 9999); setWindowTitle("服务器: 9999"); //newConnection代表有新的连接 connect(tcpServer, &QTcpServer::newConnection, [=]() { //取出建立好连接的套接字 tcpSocket = tcpServer->nextPendingConnection(); //获取对方的IP和端口 QString ip = tcpSocket->peerAddress().toString(); quint16 port = tcpSocket->peerPort(); QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port); ui->textEditRead->setText(temp); //readyRead代表读就绪 connect(tcpSocket, &QTcpSocket::readyRead, [=]() { //从通信套接字中取出内容 QByteArray array = tcpSocket->readAll(); ui->textEditRead->append(array); } ); } ); } ServerWidget::~ServerWidget() { delete ui; } void ServerWidget::on_buttonSend_clicked() { if(NULL == tcpSocket) { return; } //获取编辑区内容 QString str = ui->textEditWrite->toPlainText(); //给对方发送数据, 使用套接字是tcpSocket tcpSocket->write( str.toUtf8().data() ); } void ServerWidget::on_buttonClose_clicked() { if(NULL == tcpSocket) { return; } //主动和客户端端口连接 tcpSocket->disconnectFromHost(); tcpSocket->close(); tcpSocket = NULL; }
serverwidget.h
#ifndef SERVERWIDGET_H #define SERVERWIDGET_H #include <QWidget> #include <QTcpServer> //监听套接字 #include <QTcpSocket> //通信套接字 namespace Ui { class ServerWidget; } class ServerWidget : public QWidget { Q_OBJECT public: explicit ServerWidget(QWidget *parent = 0); ~ServerWidget(); private slots: void on_buttonSend_clicked(); void on_buttonClose_clicked(); private: Ui::ServerWidget *ui; QTcpServer *tcpServer; //监听套接字 QTcpSocket *tcpSocket; //通信套接字 }; #endif // SERVERWIDGET_H
clientwidget.cpp
#include "clientwidget.h" #include "ui_clientwidget.h" #include <QHostAddress> ClientWidget::ClientWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ClientWidget) { ui->setupUi(this); tcpSocket = NULL; //分配空间,指定父对象 tcpSocket = new QTcpSocket(this); setWindowTitle("客户端"); connect(tcpSocket, &QTcpSocket::connected, [=]() { ui->textEditRead->setText("成功和服务器建立好连接"); } ); connect(tcpSocket, &QTcpSocket::readyRead, [=]() { //获取对方发送的内容 QByteArray array = tcpSocket->readAll(); //追加到编辑区中 ui->textEditRead->append(array); } ); } ClientWidget::~ClientWidget() { delete ui; } void ClientWidget::on_buttonConnect_clicked() { //获取服务器ip和端口 QString ip = ui->lineEditIP->text(); qint16 port = ui->lineEditPort->text().toInt(); //主动和服务器建立连接 tcpSocket->connectToHost(QHostAddress(ip), port); } void ClientWidget::on_buttonSend_clicked() { //获取编辑框内容 QString str = ui->textEditWrite->toPlainText(); //发送数据 tcpSocket->write( str.toUtf8().data() ); } void ClientWidget::on_buttonClose_clicked() { //主动和对方断开连接 tcpSocket->disconnectFromHost(); tcpSocket->close(); }
clientwidget.h
#ifndef CLIENTWIDGET_H #define CLIENTWIDGET_H #include <QWidget> #include <QTcpSocket> //通信套接字 namespace Ui { class ClientWidget; } class ClientWidget : public QWidget { Q_OBJECT public: explicit ClientWidget(QWidget *parent = 0); ~ClientWidget(); private slots: void on_buttonConnect_clicked(); void on_buttonSend_clicked(); void on_buttonClose_clicked(); private: Ui::ClientWidget *ui; QTcpSocket *tcpSocket; //通信套接字 }; #endif // CLIENTWIDGET_H
如果你觉得文章还不错,记得"点赞关注"
关注我的微信公众号【 加班猿 】可以获取更多内容