毕业设计项目:QT开发基于WinSocket的FTP文件传输系统(含客户端和服务端)

基于WinSocket实现C-S文件传输系统——“闪翼文件传输系统”**

QT分别打开客户端和服务器的.pro文件载入工程,编译运行**

1、打开服务器,输入端口号并启动服务器

2、打开一个客户端,在连接服务器成功之前,并不能进行登录操作

3、客户端成功连接服务器,正确输入用户名和密码后客户端登陆成功

4、显示服务器的文件路径(服务器项目的构建文件路径)

5、显示服务器的默认文件列表(默认文件列表为服务器项目所在的文件列表)

6、上传文件到服务器(在客户端创建一个文本文件CliUpload.txt用于上传)

7、从服务器下载文件到客户端(在服务器创建一个文本文件SerDownload.txt用于下载)

8、关闭客户端,需要重连服务器且重新登陆

客户端
在这里插入图片描述
服务端
在这里插入图片描述
部分源码:

#include "clithread.h"

CliThread::CliThread(SOCKET mListen, QWidget *parent) : QThread(parent)
{
    this->mListen = mListen;
    this->parent = parent;
}

CliThread::~CliThread()
{
    closesocket(mListen);
    emit isClose();
}

void CliThread::run()
{
    //客户端地址
    sockaddr_in cli_address;
    int size = sizeof(cli_address);

    while(!isInterruptionRequested())
    {
        //每次接收新客户端时,将之前的地址信息清0
        memset(&cli_address, 0, sizeof(cli_address));

        //等待新客户端连接
        SOCKET cli_socket = accept(mListen, (SOCKADDR*)&cli_address, &size);
        if(cli_socket == INVALID_SOCKET)
        {
            msg = "创建cli_socket失败";
            emit isMsg(msg);
            return;
        }

        msg = "客户端连接成功";
        emit isMsg(msg);

        //开启新线程与客户端进行通信
        MsgThread* FileThread = new MsgThread(cli_socket, cli_address, parent);
        FileThread->start();
        //绑定信号和槽,转发消息给ui进程进行界面更新
        connect(FileThread, &MsgThread::isMsg, this, &CliThread::sendMsg);

        connect(this, &CliThread::isClose,
                [=]()
        {
            msg = "客户端断开连接";
            emit isMsg(msg);
            FileThread->terminate();
            FileThread->quit();
            delete FileThread;
        });
    }
}

void CliThread::sendMsg(QString msg)
{
    emit isMsg(msg);
    return;
}

#include "login.h"

Login::Login(QWidget *parent) : QDialog(parent)
{
    Construct();
    chances = 3;
}

//连接到serip:serport
SOCKET My_Socket;

void Login::ConnectSer()
{
    //从输入框中获取服务器地址和端口
    serip = my_severloc->text();
    serport = my_port->text();

    IP_NUM = serip;
    Port_NUM = serport;
    SOCKADDR_IN addr;
    if(WSAStartup(MAKEWORD(2, 2), &wasData) != 0)
    {
        qDebug()<<"WinSock初始化失败";
    }

    //创建套接口
    My_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(My_Socket == INVALID_SOCKET)
    {
        qDebug()<<"创建套接口失败";
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(Port_NUM.toInt());

    char* temp;
    QByteArray Tran = IP_NUM.toLatin1();
    temp = Tran.data();
    addr.sin_addr.S_un.S_addr = inet_addr(temp);
    memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero));

    if (::connect(My_Socket, (SOCKADDR*)&addr, sizeof(SOCKADDR)) == SOCKET_ERROR)  //避免与QTconnect冲突
    {
        qDebug()<<"未能连接上服务器";
        closesocket(My_Socket);
        WSACleanup();
        return;
    }

    qDebug()<<"连接成功,可进行登录";
    cli_login->setEnabled(true);
    return;
}

void Login::Login_clicked()
{
    user = my_username->text();
    psd = my_password->text();

    if((user == Name) && (psd == PassWord))
    {
        this->close();
        emit mainshow();
    }
    else
    {
        //拥有三次机会输入
        chances--;
        if(chances >= 1)
        {
            switch (chances)
            {
            case 1:
                FailedLog.setText("用户名或密码错误,您还有1次输入机会!");
                break;
            case 2:
                FailedLog.setText("用户名或密码错误,您还有2次输入机会!");
                break;
            default:
                break;
            }
            FailedLog.show();
        }
        else
        {
            ExitLog.show();
        }
    }
}

void Login::show_loginwin()
{
    this->show();
    //清空文本框,重新连接服务器
    my_severloc->clear();
    my_port->clear();
    my_username->clear();
    my_password->clear();
    //设置光标
    my_severloc->setFocus();
    cli_login->setEnabled(false);
}

void Login::Construct()
{
    this->setWindowTitle("闪翼文件传输系统-客户端登录");
    this->resize(1200, 800);
    this->setWindowIcon(QIcon(":/logo/logo.png"));
    setFixedSize(this->width(), this->height());

    QImage  image;
    image.load(":/logo/login_background.png");
    QPalette palet;
    palet.setBrush(this->backgroundRole(),QBrush(image));
    this->setPalette(palet);

    //服务器地址输入布局
    my_severloc = new QLineEdit(this);
    my_severloc->setStyleSheet("QLineEdit{border-width:0;border-style:outset;background-color:rgba(242,242,242,0)}");
    my_severloc->resize(300, 45);
    my_severloc->move(250, 340);
    my_severloc->setFont(QFont("Consolas", 15, QFont::Bold));

    my_port = new QLineEdit(this);
    my_port->setStyleSheet("QLineEdit{border-width:0;border-style:outset;background-color:rgba(242,242,242,0)}");
    my_port->resize(300, 45);
    my_port->move(250, 435);
    my_port->setFont(QFont("Consolas", 15, QFont::Bold));

    //登录界面布局
    my_username = new QLineEdit(this);
    my_username->setStyleSheet("QLineEdit{border-width:0;border-style:outset;background-color:rgba(242,242,242,0)}");
    my_username->resize(300, 55);
    my_username->move(780, 316);
    my_username->setFont(QFont("Consolas", 15, QFont::Bold));

    my_password = new QLineEdit(this);
    my_password->setStyleSheet("QLineEdit{border-width:0;border-style:outset;background-color:rgba(242,242,242,0)}");
    my_password->resize(300, 55);
    my_password->move(780, 424);
    my_password->setFont(QFont("Consolas", 15, QFont::Bold));
    my_password->setEchoMode(QLineEdit::Password);

    //按钮设置
    connectser = new QPushButton(this); connectser->resize(220,60); connectser->move(295,515);
    QString styleSheetString1("QPushButton{border-image:url(\":/logo/connect1.png\");}");
    styleSheetString1+="QPushButton:hover{border-image:url(\":/logo/connect2.png\");}";
    styleSheetString1+="QPushButton:pressed{border-image:url(\":/logo/connect3.png\");}";
    connectser->setStyleSheet(styleSheetString1);
    connect(connectser, &QPushButton::clicked, this, &Login::ConnectSer);

    cli_login = new QPushButton(this); cli_login->resize(220,60); cli_login->move(800,515);
    QString styleSheetString2("QPushButton{border-image:url(\":/logo/login1.png\");}");
    styleSheetString2+="QPushButton:hover{border-image:url(\":/logo/login2.png\");}";
    styleSheetString2+="QPushButton:pressed{border-image:url(\":/logo/login3.png\");}";
    cli_login->setStyleSheet(styleSheetString2);
    connect(cli_login, &QPushButton::clicked, this, &Login::Login_clicked);
    cli_login->setEnabled(false);

    //设置重试对话框
    FailedLog.setWindowTitle("用户登录");
    FailedLog.setWindowIcon(QIcon(":/logo/logo.png"));
    FailedLog.addButton(Retry, QMessageBox::AcceptRole);
    connect(Retry, &QPushButton::released,
            [=]()
    {
        my_username->clear();
        my_password->clear();
    });

    //设置失败对话框
    ExitLog.setWindowTitle("用户登录");
    ExitLog.setWindowIcon(QIcon(":/logo/logo.png"));
    ExitLog.setText("您的机会已用完,请您退出登录。");
    ExitLog.addButton(ExitL, QMessageBox::RejectRole);
    connect(ExitL, &QPushButton::released,
            [=]()
    {
        closesocket(My_Socket);
        WSACleanup();
        close();
    });
}

完整源码私信获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

毕业小助手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值