自己动手完成一款简易P2P共享文件软件的制作(二)


本文实验测试部分可参考基于QT的一款P2P共享文件系统
源码包下载地址基于QT的一款P2P共享文件系统下载,想要免费获取可以私信我
自己动手完成一款简易P2P共享文件软件的制作(一)


4. 客户机设计

客户机设计相较于服务器设计相对繁琐,因为除了需要设计一个GUI界面以及与服务器通信代码外,还需要增加客户端之间对等传输(P2P)相关代码。

4.1 GUI界面与功能设计

我们要为客户机设计的功能如下:

  1. 登陆
  2. 注册
  3. 获取我的共享文件信息
  4. 删除我的共享文件
  5. 上传我的共享文件
  6. 在P2P网络中搜索某个文件
  7. 从P2P网络中下载某个文件

我们将这些功能集成到一个界面中,我们设计的界面如下:
在这里插入图片描述
界面设计代码如下:
新建tcp_client.h文件,添加如下代码:

#ifndef TCP_CLIENT_H
#define TCP_CLIENT_H

#include <QMainWindow>
#include <QWidget>
#include <QListWidget>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QProgressBar>
#include <QGridLayout>
#include <QString>
#include <QTableWidget>
#include <QList>
#include <QTimer>

#include <QtNetwork/QHostAddress>
#include <QtNetwork/QTcpSocket>

class MainWindow : public QMainWindow
{
   
   
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    QWidget *myWidget;

    QListWidget *ContentListWidget;

    QLabel *UserNameLabel;
    QLineEdit *UserNameLineEdit;

    QLabel *UserPasswdLabel;
    QLineEdit *UserPasswdLineEdit;

    QLabel *ServerIPLabel;
    QLineEdit *ServerIPLineEdit;

    QLabel *PortLabel;
    QLineEdit *PortLineEdit;

    QPushButton *EnterBtn;
    QPushButton *SignBtn;

    QTableWidget *ResultTableWidget;
    QLineEdit *SearchLineEdit;
    QPushButton *SearchBtn;
    QProgressBar *ProgressBar;
    QPushButton *DownloadBtn;
    QTimer *timer;

    QTableWidget *ShareTableWidget;
    QPushButton *FlushBtn;
    QPushButton *DisableBtn;
    QPushButton *ShareBtn;

    QLineEdit *DirLineEdit;
    QPushButton *SelectDirBtn;

    QGridLayout *layout1;
    QGridLayout *layout2;
    QGridLayout *layout3;
    QGridLayout *mainLayout;

    bool status;
    int port;
    QHostAddress *ServerIP;
    QString UserName;
};
#endif // TCP_CLIENT_H

新建tcp_client.cpp文件,添加如下代码:

#include "tcp_client.h"
#include "tcp_meta.h"

#include <QMessageBox>
#include <QHostInfo>
#include <QByteArray>
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
   
   
    setWindowTitle("P2P Client");
    setGeometry(250,200,850,500);

    ContentListWidget = new QListWidget;

    myWidget = new QWidget;
    UserNameLabel = new QLabel("用户名:");
    UserNameLineEdit = new QLineEdit;
    UserPasswdLabel = new QLabel("密码:");
    UserPasswdLineEdit = new QLineEdit;
    ServerIPLabel = new QLabel("服务器IP:");
    ServerIPLineEdit = new QLineEdit("192.168.43.98");
    PortLabel = new QLabel("端口:");
    PortLineEdit = new QLineEdit;
    EnterBtn = new QPushButton("登陆");
    SignBtn = new QPushButton("注册");

    ShareTableWidget = new QTableWidget;
    ShareTableWidget->setColumnCount(6);
    QStringList tableHead;
    tableHead << "文件名" << "大小" << "文件路径" << "IP" << "端口" << "选择";
    ShareTableWidget->setHorizontalHeaderLabels(tableHead);
    FlushBtn = new QPushButton("我的共享文件");
    DisableBtn = new QPushButton("取消选中项共享");
    ShareBtn = new QPushButton("上传我的文件");

    ResultTableWidget = new QTableWidget;
    ResultTableWidget->setColumnCount(7);
    tableHead.clear();
    tableHead << "文件名" << "大小" << "文件路径" << "拥有者" << "状态" << "IP" << "选择";
    ResultTableWidget->setHorizontalHeaderLabels(tableHead);
    SearchBtn = new QPushButton("搜索");
    SearchLineEdit = new QLineEdit;
    ProgressBar = new QProgressBar;
    ProgressBar->setRange(0,100);
    DownloadBtn = new QPushButton("下载选中项");
    timer = new QTimer();

    DirLineEdit = new QLineEdit;
    SelectDirBtn = new QPushButton("选择保存位置");

    layout1 = new QGridLayout();
    layout2 = new QGridLayout();
    layout3 = new QGridLayout();
    mainLayout = new QGridLayout();

    layout1->addWidget(ContentListWidget,0,0,1,2);
    layout1->addWidget(UserNameLabel,1,0);
    layout1->addWidget(UserNameLineEdit,1,1);
    layout1->addWidget(UserPasswdLabel,2,0);
    layout1->addWidget(UserPasswdLineEdit,2,1);
    layout1->addWidget(ServerIPLabel,3,0);
    layout1->addWidget(ServerIPLineEdit,3,1);
    layout1->addWidget(PortLabel,4,0);
    layout1->addWidget(PortLineEdit,4,1);
    layout1->addWidget(EnterBtn,5,0,1,2);
    layout1->addWidget(SignBtn,6,0,1,2);
    layout2->addWidget(ShareTableWidget,0,0,1,3);
    layout2->addWidget(FlushBtn,1,0);
    layout2->addWidget(DisableBtn,1,1);
    layout2->addWidget(ShareBtn,1,2);
    layout3->addWidget(ResultTableWidget,0,0,1,2);
    layout3->addWidget(SearchLineEdit,1,0);
    layout3->addWidget(SearchBtn,1,1);
    layout3->addWidget(ProgressBar,2,0,1,2);
    layout3->addWidget(DirLineEdit,3,0);
    layout3->addWidget(SelectDirBtn,3,1);
    layout3->addWidget(DownloadBtn,4,0,1,2);


    mainLayout->addLayout(layout1,0,0,2,2);
    mainLayout->addLayout(layout2,0,2,1,1);
    mainLayout->addLayout(layout3,1,2,1,1);
    myWidget->setLayout(mainLayout);
    setCentralWidget(myWidget);

    status = false;
    port = 8010;
    PortLineEdit->setText(QString::number(port));

    ServerIP = new QHostAddress;
    
    ShareBtn->setEnabled(false);
    FlushBtn->setEnabled(false);
    DisableBtn->setEnabled(false);
    SearchBtn->setEnabled(false);
    DownloadBtn->setEnabled(false);
    
}

MainWindow::~MainWindow()
{
   
   
    delete PortLabel;
    delete PortLineEdit;
    delete EnterBtn;
    delete SignBtn;
    delete UserNameLabel;
    delete UserNameLineEdit;
    delete UserPasswdLabel;
    delete UserPasswdLineEdit;
    delete ServerIPLabel;
    delete ServerIPLineEdit;
    delete ContentListWidget;
    delete ShareTableWidget;
    delete DisableBtn;
    delete FlushBtn;
    delete ResultTableWidget;
    delete SearchLineEdit;
    delete SearchBtn;
    delete DownloadBtn;
    delete timer;
    delete ProgressBar;
    delete SelectDirBtn;
    delete DirLineEdit;
    delete layout1;
    delete layout2;
    delete layout3;
    delete mainLayout;
    delete myWidget;
    delete ServerIP;
}

在客户机中,所有要实现的功能都必须建立在客户机与服务器之间已经建立起tcp连接。而要建立连接,一种是无用户名式的请求注册连接,另一种是带用户名和密码的请求登陆连接,我们先介绍注册连接。在注册流程中,我们设定的方案是,用户先输入注册名与密码,确认服务器IP地址与端口号无误后点击注册按钮,然后等待服务器的注册回复消息,并且断开与服务器的tcp连接以便下次重新申请注册。添加的代码如下:
tcp_client.h文件:

class MainWindow : public QMainWindow
{
   
   
    enum MsgKind{
   
   
        NAMEMSG = 0,//登陆消息
        METAMSG = 1,//上传共享文件元数据消息
        DISCONNECT = 2,//断连消息
        SHAREMSG = 3,//获取我的共享文件消息
        DELETEMSG = 4,//删除共享文件元数据消息
        SEARCHMSG = 5,//搜索消息
        SIGNMSG = 6,//注册消息
        OTHERMSG = 7//普通消息
    };
private...
    QTcpSocket *tcpSocket;
    void FormatMsg(QString &msg, MsgKind kind);
public slots:
    void slotSignUp();//注册按钮对应的槽函数
    void SignConnected();//注册的tcp建立连接后进入该函数
    void SignDisconnected();//注册的tcp断开连接后进入该函数
    void SignDataReceived();//注册过程中,服务器发送来消息会进入该函数
    ...
};

tcp_client.cpp文件:

void MainWindow::SignConnected(){
   
   
    SignBtn->setEnabled(false);

    int length = 0;
    QString passwd = UserPasswdLineEdit->text();
    //分号用于隔开两个字符串
    QString msg = UserName + ";" + passwd + ";";
    FormatMsg(msg, SIGNMSG);//格式化注册消息
    if((length = tcpSocket->write(msg.toLatin1(),msg.length())) != msg.length()){
   
   
        return;
    }
}
void MainWindow::
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值