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