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参数默认为0void 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 servertcpsocket->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();
}