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();
}