1 基础知识
udp
tcp
2 UDP
框架
客户端:
QUdpSocket x;
qint64 writeDatagram(
const char *data,
qint64 size,
const QHostAddress &address,
quint16 port
);
服务器:
void Server::initSocket(){
udpSocket = new QUdpSocket(this);
udpSocket->bind(QHostAddress::LocalHost, 7755);
connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(readPendingDatagrams()));
}
2.1 客户端示例:
网络编程都需添加network(后面不再提醒)
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTextEdit>
#include <QLineEdit>
#include <QPushButton>
#include <QUdpSocket>
#include <QHostAddress>
class Widget : public QWidget
{
Q_OBJECT
public slots:
void senddata()
{
udpsock->writeDatagram(le->text().toStdString().c_str(), QHostAddress("192.168.31.124"), 8888);
}
void recvdata()
{
QByteArray datagram;
datagram.resize(udpsock->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpsock->readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);
te->append(datagram);
}
public:
Widget(QWidget *parent = 0);
~Widget();
private:
QTextEdit *te;
QLineEdit *le;
QPushButton *pb;
QUdpSocket *udpsock;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QVBoxLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
te = new QTextEdit;
le = new QLineEdit;
pb = new QPushButton("send");
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(te);
vbox->addWidget(le);
vbox->addWidget(pb);
setLayout(vbox);
udpsock = new QUdpSocket;
connect(pb, SIGNAL(clicked(bool)), this, SLOT(senddata()));
connect(udpsock, SIGNAL(readyRead()), this, SLOT(recvdata()));
}
Widget::~Widget()
{
}
2.2 服务端
添加network
udpserver.h
#ifndef UDPSERVER_H // 如果UDPSERVER_H没有被定义
#define UDPSERVER_H // 定义UDPSERVER_H
#include <QObject> // 包含QObject的头文件,QObject是所有Qt对象的基类
#include <QUdpSocket> // 包含QUdpSocket的头文件,用于UDP通信
#include <QDebug> // 包含QDebug的头文件,用于在调试时输出信息
// 声明udpServer类,继承自QObject
class udpServer : public QObject
{
Q_OBJECT // 启用Qt的信号和槽机制
public:
explicit udpServer(QObject *parent = 0); // 构造函数,explicit防止隐式转换,可选的parent参数默认为0
void init() // 初始化函数
{
udpSocket = new QUdpSocket(this); // 创建QUdpSocket对象
udpSocket->bind(QHostAddress::AnyIPv4, 8888); // 绑定到任意IPv4地址的8888端口
// 连接QUdpSocket的readyRead信号到本类的readPendingDatagrams槽,当有数据可读时触发
connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(readPendingDatagrams()));
qDebug()<<"init...."; // 使用QDebug输出初始化信息
}
signals: // 信号部分,此处未定义任何信号
public slots: // 槽部分
void readPendingDatagrams() // 当有数据待读取时,会调用此函数
{
while (udpSocket->hasPendingDatagrams()) { // 循环处理所有待读取的数据报
QByteArray datagram; // 用于存储接收到的数据报
datagram.resize(udpSocket->pendingDatagramSize()); // 调整大小以匹配待读取数据报的大小
QHostAddress sender; // 发送者的地址
quint16 senderPort; // 发送者的端口
// 读取数据报,并保存发送者的地址和端口
udpSocket->readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);
//processTheDatagram(datagram); // 处理数据报的函数
qDebug()<<"recv: "<<datagram; // 使用QDebug输出接收到的数据报
// 将接收到的数据报原样发送回去
udpSocket->writeDatagram(datagram.data(), datagram.size(),
sender, senderPort);
}
}
private:
QUdpSocket *udpSocket; // 指向QUdpSocket对象的指针
};
#endif // UDPSERVER_H // 结束预处理器指令
udpserver.cpp
#include "udpserver.h"
udpServer::udpServer(QObject *parent) : QObject(parent)
{
}
main.cpp
#include <QCoreApplication>
#include <udpserver.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
udpServer server;
server.init();
return a.exec();
}
最终效果:
3 TCP
框架
客户端:
mytcpsock = new QTcpSocket;
Mytcpsock->connectToHost(
QHostAddress("192.168.4.222"), 8888);
connect(mytcpsock, SIGNAL(readyRead()), this, SLOT(read_data()));
服务器:
Server::Server(QObject *parent) : QObject(parent)
{
tcpserver = new QTcpServer;
tcpserver->listen(QHostAddress::AnyIPv4, 8888);
connect(tcpserver, SIGNAL(newConnection()),
this, SLOT(new_client()));
tcpserver->waitForNewConnection();
}
3.1 客户端
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
#include <QTcpSocket>
class Widget : public QWidget
{
Q_OBJECT
public slots:
void senddata()
{
tcpsocket->write(le->text().toStdString().c_str());
}
void recvdata()
{
QByteArray buf = tcpsocket->readAll();
te->append(buf);
}
public:
Widget(QWidget *parent = 0);
~Widget();
private:
QLineEdit *le;
QPushButton *pb;
QTextEdit *te;
QTcpSocket *tcpsocket;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QVBoxLayout>
#include <QHostAddress>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
le = new QLineEdit;
pb = new QPushButton("senddata");
te = new QTextEdit;
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(te);
vbox->addWidget(le);
vbox->addWidget(pb);
setLayout(vbox);
tcpsocket = new QTcpSocket;
//connect to server
tcpsocket->connectToHost(QHostAddress("192.168.1.155"), 8888);
connect(pb, SIGNAL(clicked(bool)), this, SLOT(senddata()));
connect(tcpsocket, SIGNAL(readRead()), this, SLOT(recvdata()));
}
Widget::~Widget()
{
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
3.2 服务端
tcpServer.h
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>
class TcpServer : public QObject
{
Q_OBJECT // 启用Qt的信号和槽机制
public:
explicit TcpServer(QObject *parent = 0);
public slots:
void newConnected()
{
qDebug() << "connected";
clientsock = ser->nextPendingConnection(); //得到客户端
connect(clientsock, SIGNAL(readyRead()), this, SLOT(recvData()));
}
void recvData()
{
QByteArray buf = clientsock->readAll();
qDebug()<<"recv:"<<buf;
clientsock->write(buf);
}
private:
QTcpServer *ser;
QTcpSocket *clientsock;
};
#endif // TCPSERVER_H
tcpServer.cpp
#include "tcpServer.h"
TcpServer::TcpServer(QObject *parent) : QObject(parent)
{
ser = new QTcpServer;
ser->listen(QHostAddress::AnyIPv4, 8888); //监听端口
connect(ser, SIGNAL(newConnection()), this, SLOT(newConnected())); //当新客户端来了与槽函数newConnected挂接上
ser->waitForNewConnection(); //开启监听
}
main.cpp
#include <QCoreApplication>
#include "tcpserver.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
TcpServer server;
return a.exec();
}