一、服务器
1.1 ui设计
1.1.1 图像展示
1.1.2 类名定义
1.2 代码展示
1.2.1 mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QWidget>
#include <QThread>
#include <QTcpSocket>
#include <QDebug>
class Mythread : public QThread
{
Q_OBJECT
public:
explicit Mythread(QTcpSocket *s);
void run();
signals:
void SendToWidget(QByteArray ba);
public slots:
void ClientinfoSlots();
void ThreadSlots(QByteArray ba);
private:
QTcpSocket *sock;
};
#endif
1.2.2 widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
#include <QTcpServer>
#include "mythread.h"
#define PORT 8000
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void NewClientHandeler();
void ClientInfiSlots();
void ThreadSlots(QByteArray ba);
private:
Ui::Widget *ui;
QTcpServer *Tcpserver;
QTcpSocket *socket;
};
#endif
1.2.3 mian.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
1.2.4 mythread.cpp
#include "mythread.h"
Mythread::Mythread(QTcpSocket *s)
{
sock = s;
}
void Mythread::run()
{
connect(sock,&QTcpSocket::readyRead,this,&Mythread::ClientinfoSlots);
}
void Mythread::ClientinfoSlots()
{
QByteArray ba = sock->readAll();
emit SendToWidget(ba);
}
1.2.5 widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
Tcpserver = new QTcpServer;
socket = new QTcpSocket;
Tcpserver->listen(QHostAddress::AnyIPv4,PORT);
connect(Tcpserver,&QTcpServer::newConnection,this,&Widget::NewClientHandeler);
}
Widget::~Widget()
{
delete ui;
}
void Widget::NewClientHandeler()
{
socket = Tcpserver->nextPendingConnection();
socket->peerPort();
socket->peerAddress();
ui->IplineEdit->setText(socket->peerAddress().toString());
ui->PortlineEdit->setText(QString::number(socket->peerPort()));
Mythread *t = new Mythread(socket);
t->start();
connect(t,&Mythread::SendToWidget,this,&Widget::ThreadSlots);
}
void Widget::ClientInfiSlots()
{
ui->MesglineEdit->setText(QString(socket->readAll()));
}
void Widget::ThreadSlots(QByteArray ba)
{
ui->MesglineEdit->setText(QString(ba));
}
二、客户端
2.1 ui设计
2.1.1 图像展示
2.1.2 类名定义
2.2 代码展示
2.2.1 chat.h
#ifndef CHAT_H
#define CHAT_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class chat;
}
class chat : public QWidget
{
Q_OBJECT
public:
explicit chat(QTcpSocket *s,QWidget *parent = 0);
~chat();
private slots:
void on_SendButton_clicked();
void on_ClearButton_clicked();
void on_CloseButton_clicked();
private:
Ui::chat *ui;
QTcpSocket *sock;
};
#endif
2.2.2 widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
#include <QMessageBox>
#include <QHostAddress>
#include "chat.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_ConnectButton_clicked();
void on_CloseButton_clicked();
private:
Ui::Widget *ui;
QTcpSocket *sock;
};
#endif
2.2.3 chat.cpp
#include "chat.h"
#include "ui_chat.h"
chat::chat(QTcpSocket *s,QWidget *parent) :
QWidget(parent),
ui(new Ui::chat)
{
ui->setupUi(this);
sock = s;
}
chat::~chat()
{
delete ui;
}
void chat::on_SendButton_clicked()
{
QByteArray ba;
ba.append(ui->MesglineEdit->text());
sock->write(ba);
}
void chat::on_ClearButton_clicked()
{
ui->MesglineEdit->clear();
}
void chat::on_CloseButton_clicked()
{
this->close();
}
2.2.4 main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
2.2.5 widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
sock = new QTcpSocket;
connect(sock,&QTcpSocket::connected,[this](){
QMessageBox::information(this,"连接提示","连接成功");
this->hide();
chat *c = new chat(sock);
c->show();
});
connect(sock,&QTcpSocket::disconnected,[this](){
QMessageBox::warning(this,"连接提示","网络断开");
});
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_ConnectButton_clicked()
{
QString Ipaddr = ui->iplineEdit->text();
QString Port = ui->PortlineEdit->text();
sock->connectToHost(QHostAddress(Ipaddr),Port.toShort());
}
void Widget::on_CloseButton_clicked()
{
this->close();
}
三、最终成果
四、对于线程信号的理解
线程这个逻辑流程,就是首先子客户端建立连接,之后将信号传入线程函数,发射信号,传入服务器进程处理
|