

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include
#include
#include
#include
#include
//继承QThread这个类,
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 // MYTHREAD_H
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#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 // WIDGET_H
#include "widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#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);
}
#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;
//监听任何IPv4地址,PORT是写死8000的
Tcpserver->listen(QHostAddress::AnyIPv4,PORT);
//客户端发起连接,server会发出信号
connect(Tcpserver,&QTcpServer::newConnection,this,&Widget::NewClientHandeler);
}
Widget::~Widget()
{
delete ui;
}
void Widget::NewClientHandeler()
{
//建立tcp连接
socket = Tcpserver->nextPendingConnection();//socket就包含了这个客户端的所有消息
socket->peerPort(); //对端(客户端)的端口
socket->peerAddress(); //对端(客户端)的ip地址
//进行显示
ui->IplineEdit->setText(socket->peerAddress().toString());
ui->PortlineEdit->setText(QString::number(socket->peerPort()));
//判断是发信息的,不是发起连接的,之后进行槽函数处理
//connect(socket,&QTcpSocket::readyRead,this,&Widget::ClientInfiSlots);
//创建新线程(new 一个对象)
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));
}




#ifndef CHAT_H
#define CHAT_H
#include
#include
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 // CHAT_H
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
#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 // WIDGET_H
#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();
}
#include "widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#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,"连接提示","连接成功");
//连接成功将隐藏当前窗口,进入chat页面
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()
{
//连接ip地址和窗口
QString Ipaddr = ui->iplineEdit->text();
QString Port = ui->PortlineEdit->text();
//连接服务器
sock->connectToHost(QHostAddress(Ipaddr),Port.toShort());
}
void Widget::on_CloseButton_clicked()
{
this->close();
}

线程这个逻辑流程,就是首先子客户端建立连接,之后将信号传入线程函数,发射信号,传入服务器进程处理