qt 下UDP消息的接收和发送和TCP发送文件

时间:2022-12-15 15:19:21
 
UDP发送消息实现代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QUdpSocket>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
private:
    QLabel *label1, *label2, *label3, *label4;
    QLineEdit *edit1, *edit2, *edit3, *edit4;
    QPushButton *btn1, *btn2;
    QUdpSocket *udpsocket;
private slots:
    void on_clicked1();
    void on_clicked2();
    void dataReceived();
};

#endif // WIDGET_H


 
#include "widget.h"
#include <QHBoxLayout>
#include <QMessageBox>
#include <QList>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    udpsocket = new QUdpSocket(this);
    setWindowTitle(tr("udp聊天"));
    label1 = new QLabel;
    label1->setText("请输入bind端口号");
    label2 = new QLabel;
    label2->setText("请输入目的IP地址");
    label3 = new QLabel;
    label3->setText("请输入目的端口号");
    label4 = new QLabel;
    label4->setText("请输入发送的消息");

    edit1 = new QLineEdit;
    edit2 = new QLineEdit;
    edit3 = new QLineEdit;
    edit4 = new QLineEdit;

    btn1 = new QPushButton;
    btn1->setText(tr("bind"));
    btn2 = new QPushButton;
    btn2->setText(tr("发送"));

    QGridLayout *layout1 = new QGridLayout(this);
    layout1->addWidget(label1, 0, 0);
    layout1->addWidget(edit1, 0, 1);
    layout1->addWidget(btn1, 1, 0);
    layout1->addWidget(label2, 2, 0);
    layout1->addWidget(edit2, 2, 1);
    layout1->addWidget(label3, 3, 0);
    layout1->addWidget(edit3, 3, 1);
    layout1->addWidget(label4, 4, 0);
    layout1->addWidget(edit4, 4, 1);
    layout1->addWidget(btn2, 5, 0);

    connect(btn1, SIGNAL(clicked()), this, SLOT(on_clicked1()));
    connect(btn2, SIGNAL(clicked()), this, SLOT(on_clicked2()));
    connect(udpsocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
}

Widget::~Widget()
{

}


void Widget::on_clicked1()
{
    udpsocket->close();
    udpsocket->bind(edit1->text().toInt());
}

void Widget::on_clicked2()
{
    QHostAddress addr;
    addr.setAddress(edit2->text());
    int port = edit3->text().toInt();
    udpsocket->writeDatagram(edit4->text().toUtf8(), addr, port);
}

void Widget::dataReceived()
{
    QHostAddress addr;
    char buf[1024];
    while (udpsocket->hasPendingDatagrams())
    {
        memset(buf, 0, sizeof(buf));
        udpsocket->readDatagram(buf, sizeof(buf), &addr);
        QMessageBox::information(this, tr("消息"), tr("来自") + addr.toString() + tr("的消息:\n") + buf);
    }
}

TCP发送文件实现代码,
客户端代码
 
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QTcpServer>

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QLabel *label1, *label2;
    QLineEdit *edit1, *edit2;
    QPushButton *btn1;
    QTcpSocket *tcpsocket;

    QString filename;

private slots:
    void on_clicked1();
    void dataReceived();
};

#endif // DIALOG_H

#include "dialog.h"

#include <QGridLayout>
#include <QFileDialog>
#include <QTcpSocket>

#define BUFSIZE 262144 // 256K

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    tcpsocket = new QTcpSocket(this);

    setWindowTitle(tr("tcp文件发送客户端"));
    label1 = new QLabel;
    label1->setText(tr("请输入目的IP地址"));
    label2 = new QLabel;
    label2->setText(tr("请输入目的端口号"));

    edit1 = new QLineEdit;
    edit2 = new QLineEdit;

    btn1 = new QPushButton;
    btn1->setText(tr("发送文件"));

    QGridLayout *layout = new QGridLayout(this);

    layout->addWidget(label1, 0, 0);
    layout->addWidget(edit1, 0, 1);
    layout->addWidget(label2, 1, 0);
    layout->addWidget(edit2, 1, 1);
    layout->addWidget(btn1, 2, 0);

    connect(btn1, SIGNAL(clicked()), this, SLOT(on_clicked1()));
    connect(tcpsocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
}

Dialog::~Dialog()
{

}

void getfilename(const char *filename, char *name)
{
    int len = strlen(filename);
    int i;
    for (i = (len - 1); i >= 0; i--)
    {
        if ((filename[i] == '\\') || (filename[i] == '/'))
        {
            break;
        }
    }
    strcpy(name, &filename[i + 1]);
}

void Dialog::on_clicked1()
{
    filename = QFileDialog::getOpenFileName(this, tr("打开文件"));
    if (!filename.isEmpty())
    {
        tcpsocket->close();
        QHostAddress serverIP;
        serverIP.setAddress(edit1->text());
        tcpsocket->connectToHost(serverIP, edit2->text().toInt());

        char buf[1024];
        memset(buf, 0, sizeof(buf));

        getfilename(filename.toStdString().data(), buf);
        tcpsocket->write(buf, strlen(buf));
    }
}

void Dialog::dataReceived()
{
    char *buf = (char *)malloc(BUFSIZE);

    while (tcpsocket->bytesAvailable() > 0)
    {
        memset(buf, 0, BUFSIZE);
        tcpsocket->read(buf, BUFSIZE);
    }

    if (strncmp(buf, "OK", 2) == 0)// 服务端回复统一接受文件
    {
        FILE *fd = fopen(filename.toStdString().data(), "rb");// 只读方式打开
        if (fd)
        {
            while (1)
            {
                memset(buf, 0, BUFSIZE);
                size_t rc = fread(buf, 1, BUFSIZE, fd);//循环读取文件,知道读到文件尾
                if (rc <= 0)
                {
                    break;
                }
                else
                {
                    tcpsocket->write(buf, rc);
                    if (rc <= 0)
                    {
                        break;
                    }
                }
            }
        }
        fclose(fd);
    }
    tcpsocket->close();
    free(buf);
}

服务器代码参看前边的TCP文件传送博文