Qt-Day12-学习笔记

Qt-Day12-学习笔记_第1张图片

文件传输

  • 1. windows的文件传输
  • 2. Qt上的文件传输

1. windows的文件传输

Qt-Day12-学习笔记_第2张图片
服务器端:


#include 
#pragma comment(lib,"Ws2_32.lib ")
#include 
#include 


int main(){
	//0 请求协议版本
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (LOBYTE(wsaData.wVersion) != 2 ||
		HIBYTE(wsaData.wVersion) != 2){
		printf("请求协议版本失败:%d\n", GetLastError());
		return -1;
	}
	printf("请求协议版本成功!\n");

	//1 创建socket
	SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (SOCKET_ERROR == serverSocket){
		printf("创建socket失败:%d\n", GetLastError());
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("创建socket成功!\n");

	//2 服务器协议地址簇
	SOCKADDR_IN sAddr = { 0 };
	sAddr.sin_family = AF_INET;								// 和socket第一个参数一致
	sAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");	// 把数点格式字符串转换成网络字节序
	sAddr.sin_port = htons(10086);							// 65536   5000以上    大小端转换

	//3 绑定
	int r = bind(serverSocket, (sockaddr*)&sAddr, sizeof sAddr);
	if (-1 == r){
		printf("绑定失败:%d\n", GetLastError());
		//7 关闭socket
		closesocket(serverSocket);
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("绑定成功!\n");

	//4 监听
	r = listen(serverSocket, 10);
	if (-1 == r){
		printf("监听失败:%d\n", GetLastError());
		//7 关闭socket
		closesocket(serverSocket);
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("监听成功!\n");

	//5 等待客户端连接
	SOCKADDR_IN cAddr = { 0 };
	int len = sizeof cAddr;
	SOCKET clientSocket = accept(serverSocket, (sockaddr*)&cAddr, &len);//阻塞
	if (SOCKET_ERROR == clientSocket){
		printf("客户端连接失败:%d\n", GetLastError());
		//7 关闭socket
		closesocket(serverSocket);
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("有客户端连接到服务器了:%s,%d!\n",
		inet_ntoa(cAddr.sin_addr), ntohl(cAddr.sin_port));


	//6 接受文件名和文件大小
	char fileName[MAX_PATH] = { 0 };
	int fileSize = 0;

	r = recv(clientSocket, fileName, MAX_PATH - 1, NULL);
	if (r > 0){
		printf("接受到文件名:%s\n", fileName);
	}
	r = recv(clientSocket, (char*)&fileSize, 4, NULL);
	if (4 == r){
		printf("接受到文件大小:%d\n", fileSize);
	}

	FILE* fp = fopen(fileName, "wb");

	int count = 0;
	char temp[1024];
	while (1){
		memset(temp, 0, 1024);
		r = recv(clientSocket, temp, 1024, NULL);
		if (r > 0){
			count += r;
			fwrite(temp, 1, r, fp);
			if (count >= fileSize) break;
		}
	}

	printf("接收完毕!\n");
	fclose(fp);
	while (1);
}

客户端:

#include 
#pragma comment(lib,"Ws2_32.lib ")
#include 
#include 


#include 
#pragma comment(lib,"Ws2_32.lib ")
#include 
#include 



int main(){
	//0 请求协议版本
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (LOBYTE(wsaData.wVersion) != 2 ||
		HIBYTE(wsaData.wVersion) != 2){
		printf("请求协议版本失败:%d\n", GetLastError());
		return -1;
	}
	printf("请求协议版本成功!\n");

	//1 创建socket
	SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (SOCKET_ERROR == serverSocket){
		printf("创建socket失败:%d\n", GetLastError());
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("创建socket成功!\n");

	//2 服务器协议地址簇
	SOCKADDR_IN sAddr = { 0 };
	sAddr.sin_family = AF_INET;								// 和socket第一个参数一致
	sAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");	// 把数点格式字符串转换成网络字节序
	sAddr.sin_port = htons(10086);							// 65536   5000以上    大小端转换


	//3 连接服务器
	int r = connect(serverSocket, (sockaddr*)&sAddr, sizeof sAddr);
	if (-1 == r){
		printf("连接服务器失败:%d\n", GetLastError());
		//7 关闭socket
		closesocket(serverSocket);
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("连接服务器成功!\n");

	//4 通信
	//4.1 获取文件名和文件大小
	char fileName[MAX_PATH] = { 0 };
	printf("请输入要发送的文件名:");
	scanf("%s", fileName);

	send(serverSocket, fileName, strlen(fileName), NULL);

	//4.2 获取文件大小
	FILE* fp = fopen(fileName, "rb");
	if (fp == NULL)
		return -1;
	
	fseek(fp, 0, SEEK_END);
	int fileSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);

	printf("fileSize:%d\n", fileSize);
	//4.3 发送文件大小
	send(serverSocket, (char*)&fileSize, 4, NULL);

	//4.4 读取并循环发送文件内容
	char temp[1024];
	while (1){
		r = fread(temp, 1, 1024, fp);
		if (r > 0){
			send(serverSocket, temp, r, NULL);
		}
		else{
			break;
		}
	}
	//4.5 关闭文件
	fclose(fp);

	//5 关闭socket
	closesocket(serverSocket);
	//6 清理协议版本信息
	WSACleanup();

	while (1);
	return 0;
}

Qt-Day12-学习笔记_第3张图片Qt-Day12-学习笔记_第4张图片

2. Qt上的文件传输

Qt-Day12-学习笔记_第5张图片
服务器端:

#include "widget.h"
#include "ui_widget.h"
#pragma execution_character_set("utf-8")

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("文件传输服务器s");
    ui->progressBar->setValue(0);
    fileSize = 0;
    isInfo = true;
    //1 准备网络连接
    //1.1 创建socket对象
    pTcpServer = new QTcpServer(this);
    //1.2 监听
    pTcpServer->listen(QHostAddress::Any,9527);

    //2 等待客户端连接
    connect(pTcpServer,&QTcpServer::newConnection,
            [=](){
                //2.1 接受客户端连接
                pTcpSocket = pTcpServer->nextPendingConnection();
                //2.2 显示
                QString ip = pTcpSocket->peerAddress().toString();
                quint16 port = pTcpSocket->peerPort();

                QString str = QString("客户端连接服务器成功  ip:%1,port:%2").arg(ip).arg(port);
                ui->textEdit->append(str);


                //3 接受客户端发来的数据
                connect(pTcpSocket,&QTcpSocket::readyRead,
                        [=](){
                            QByteArray buff;
                            buff = pTcpSocket->readAll();
                            if(isInfo){//3.1 是文件信息
                                isInfo = false;
                                m_fileName = QString(buff).section("--",0,0);
                                m_fileSize = QString(buff).section("--",1,1).toInt();

                                ui->textEdit->append(buff);
                                QString temp = QString("文件名:%1,文件大小:%2").arg(m_fileName).arg(m_fileSize);
                                ui->textEdit->append(temp);

                                //4 创建并打开文件
                                file.setFileName(m_fileName);
                                bool is = file.open(QIODevice::WriteOnly);
                                if(is){
                                    qDebug() << "创建文件成功";
                                }else{
                                    qDebug() << "创建文件失败";
                                }
                            }else{//3.2 是文件内容
                                //把接收到的文件内容写入文件中
                                qint64 r = file.write(buff);
                                fileSize +=r;
                                //设置进度条
                                ui->progressBar->setValue(100 * fileSize/m_fileSize);
                                if(fileSize>=m_fileSize){
                                    ui->textEdit->append("接收完毕");
                                    file.close();
                                    pTcpSocket->disconnect();
                                    pTcpSocket->close();
                                }
                            }
                });

    });


}

Widget::~Widget()
{
    delete ui;
}


客户端:

#include "clientwidget.h"
#include "ui_clientwidget.h"
#pragma execution_character_set("utf-8")

clientWidget::clientWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::clientWidget)
{
    ui->setupUi(this);
    setWindowTitle("文件传输客户端c");
    fileSize = 0;
    ui->btnOpen->setEnabled(false);
    ui->btnSend->setEnabled(false);
    //1 创建对象
    pTcpSocket = new QTcpSocket(this);

    //3 判定是否连接上服务器
    connect(pTcpSocket,&QTcpSocket::connected,
            [=](){
                ui->textEdit->append("连接服务器成功!");
                ui->btnOpen->setEnabled(true);
                ui->btnConnect->setEnabled(false);



    });

    //4.3 服务器等待完毕,开始发送文件内容
    connect(&timer,&QTimer::timeout,
            [=](){
                timer.stop();//关掉
                //4.4 发送文件内容
                ui->textEdit->append("开始发送文件内容");
                sendData();
    });

}
//发送文件内容的函数
void clientWidget::sendData(){
    qint64 r;
    char buff[1024];

    while(1){
        r = file.read(buff,1024);
#if 1
        if(r > 0){
            fileSize += r;//已经读取了多少
            pTcpSocket->write(buff,r);
            if(fileSize>=m_fileSize) break;
        }else{//读完了
            break;
        }
#else
       if(r<=0) break;
       r = pTcpSocket->write(buff,r);
       fileSize += r;
       if(fileSize>=m_fileSize) break;
#endif
    }
    file.close();
}
clientWidget::~clientWidget()
{
    delete ui;
}
//2 连接服务器
void clientWidget::on_btnConnect_clicked()
{
    QString ip = ui->lineEditIP->text();
    quint16 port = ui->lineEditPORT->text().toUInt();


    pTcpSocket->connectToHost(ip,port);
}
//3 打开文件并获取文件信息
void clientWidget::on_btnOpen_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,"打开要发送的文件","C:/Users/Administrator/Desktop",
                                 "TXT(*.txt);;DOC(*.doc);;jpg(*.jpg);;ALL(*.*)");

    if(!fileName.isEmpty()){
        m_fileName.clear();
        m_fileSize = 0;

        QFileInfo info(fileName);
        m_fileName = info.fileName();
        m_fileSize = info.size();

        QString str = QString("文件名:%1,文件大小:%2").arg(m_fileName).arg(m_fileSize);
        ui->textEdit->append(str);

        //打开

        //fileName 带路径
        //m_fileName 只有文件名
        file.setFileName(fileName);
        bool is = file.open(QIODevice::ReadOnly);
        if(is){
            ui->textEdit->append("准备发送的路径:");
            ui->textEdit->append(fileName);

            ui->btnOpen->setEnabled(false);
            ui->btnSend->setEnabled(true);
        }else{
            qDebug() << "打开文件:" << fileName << "失败";
        }
    }


}

//4 发送
void clientWidget::on_btnSend_clicked()
{
    //4.1 发送文件信息
    QString fileInfo = QString("%1--%2").arg(m_fileName).arg(m_fileSize);
    qint64 ret = pTcpSocket->write(fileInfo.toUtf8());
    if(ret > 0){
        qDebug() << "发送文件信息成功";
        //4.2 等一下下(等服务器接受文件信息并创建文件)
        timer.start(30);//每间隔30ms发送一次定时器信号
    }else{
        qDebug() << "发送文件信息失败";
        file.close();
        ui->btnOpen->setEnabled(true);
        ui->btnSend->setEnabled(false);
    }


}

Qt-Day12-学习笔记_第6张图片
Qt-Day12-学习笔记_第7张图片

你可能感兴趣的:(学习笔记,qt)